programing

자바에서는 어떤 컨스트럭터를 다른 컨스트럭터에서 어떻게 호출합니까?

sourcetip 2022. 7. 19. 23:16
반응형

자바에서는 어떤 컨스트럭터를 다른 컨스트럭터에서 어떻게 호출합니까?

다른(하위 클래스가 아닌 같은 클래스 내)에서 생성자를 호출할 수 있습니까?만약 그렇다면 어떻게?그리고 다른 컨스트럭터(여러 가지 방법이 있는 경우)를 호출하는 가장 좋은 방법은 무엇일까요?

네, 가능합니다.

public class Foo {
    private int x;

    public Foo() {
        this(1);
    }

    public Foo(int x) {
        this.x = x;
    }
}

의 슈퍼클래스 컨스트럭터가 을 하려면 , 「」를 합니다.superthis. 컨스트럭터에는 1개의 컨스트럭터만 연결할 수 있으며 컨스트럭터 본문의 첫 번째 문이어야 합니다.

관련 질문도 참조해 주세요.이 질문은 C#에 관한 것이지만 같은 원칙이 적용되는 경우입니다.

「」를 사용합니다.this(args)가장 작은 컨스트럭터부터 가장 큰 컨스트럭터까지 작업하는 것이 좋습니다.

public class Cons {

    public Cons() {
        // A no arguments constructor that sends default values to the largest
        this(madeUpArg1Value,madeUpArg2Value,madeUpArg3Value);
    }

    public Cons(int arg1, int arg2) {
       // An example of a partial constructor that uses the passed in arguments
        // and sends a hidden default value to the largest
        this(arg1,arg2, madeUpArg3Value);
    }

    // Largest constructor that does the work
    public Cons(int arg1, int arg2, int arg3) {
        this.arg1 = arg1;
        this.arg2 = arg2;
        this.arg3 = arg3;
    }
}

또한 최근에 주창된 가치 Of 또는 "of" 접근 방식을 사용할 수도 있습니다.

public class Cons {
    public static Cons newCons(int arg1,...) {
        // This function is commonly called valueOf, like Integer.valueOf(..)
        // More recently called "of", like EnumSet.of(..)
        Cons c = new Cons(...);
        c.setArg1(....);
        return c;
    }
} 

클래스를 하려면 , 「」를 사용합니다.super(someValue)super에 대한 호출은 컨스트럭터 내의 첫 번째 호출이어야 합니다.그렇지 않으면 컴파일러 오류가 발생합니다.

[주의: 다른 답변에서는 볼 수 없었던1가지 측면을 추가하고 싶습니다.이것은, this()가 첫 번째 행에 있어야 하는 요건의 한계를 극복하는 방법입니다.]

할 수 .this(), ' '다', '다만', '다만', '다만', '다만', '다만', '다만', 이렇게.this첫 번째 줄에 있어야 합니다.

public class MyClass {

  public MyClass(double argument1, double argument2) {
    this(argument1, argument2, 0.0);
  }

  public MyClass(double argument1, double argument2, double argument3) {
    this.argument1 = argument1;
    this.argument2 = argument2;
    this.argument3 = argument3;
  }
}

★★★this는 첫 번째 줄에 표시되어야 하지만 큰 제한처럼 보이지만 정적 메서드를 사용하여 다른 생성자의 인수를 구성할 수 있습니다.예를 들어 다음과 같습니다.

public class MyClass {

  public MyClass(double argument1, double argument2) {
    this(argument1, argument2, getDefaultArg3(argument1, argument2));
  }

  public MyClass(double argument1, double argument2, double argument3) {
    this.argument1 = argument1;
    this.argument2 = argument2;
    this.argument3 = argument3;
  }

  private static double getDefaultArg3(double argument1, double argument2) {
    double argument3 = 0;

    // Calculate argument3 here if you like.

    return argument3;

  }

}

코드 내부에서 다른 컨스트럭터를 호출해야 할 경우(첫 번째 회선이 아님) 보통 다음과 같은 도우미 방식을 사용합니다.

class MyClass {
   int field;


   MyClass() {
      init(0);
   } 
   MyClass(int value) {
      if (value<0) {
          init(0);
      } 
      else { 
          init(value);
      }
   }
   void init(int x) {
      field = x;
   }
}

그러나 대부분의 경우 저는 가능한 한 복잡한 컨스트럭터를 첫 번째 줄에 있는 간단한 컨스트럭터에서 호출함으로써 그 반대로 하려고 합니다.위의 예에서는

class MyClass {
   int field;

   MyClass(int value) {
      if (value<0)
         field = 0;
      else
         field = value;
   }
   MyClass() {
      this(0);
   }
}

에서는, 「」를 할 수 .this키워드를 지정하여 같은 클래스의 다른 컨스트럭터를 호출합니다.이를 명시적 생성자 호출이라고 합니다.

오브젝트 섹션의 실장과는 다른 Rectangle 클래스가 있습니다.

public class Rectangle {
    private int x, y;
    private int width, height;

    public Rectangle() {
        this(1, 1);
    }
    public Rectangle(int width, int height) {
        this( 0,0,width, height);
    }
    public Rectangle(int x, int y, int width, int height) {
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;
    }

}

이 클래스에는 생성자 집합이 포함되어 있습니다.각 생성자는 직사각형의 일부 또는 모든 멤버 변수를 초기화합니다.

은 '아예', '아예', '아예'를 사용합니다.this(…)이는 명시적 생성자 호출이라고 합니다.

단, 이러한 명시적인 컨스트럭터 호출 스테이트먼트에서는 다음 명령어참조할 수 없습니다.

  • 임의의 인스턴스 변수 또는
  • 인스턴스 메서드 또는
  • 이 클래스 또는 슈퍼 클래스에 선언된 내부 클래스 또는
  • this ★★★★★★★★★★★★★★★★★」
  • super.

JLS(제8.8.7.1절)에 기재된 바와 같이.

할 수 , 가 이 할 수 .this()]this() 콜('')this★★★★★★★★★★★★★★★★★★」this() ★★★★★★★★★★★★★★★★★」this(args)는 컨스트럭터의 첫 번째 행이어야 합니다.

예:

Class Test {
    Test() {
        this(10); // calls the constructor with integer args, Test(int a)
    }
    Test(int a) {
        this(10.5); // call the constructor with double arg, Test(double a)
    }
    Test(double a) {
        System.out.println("I am a double arg constructor");
    }
}

이를 컨스트럭터 오버로드라고 합니다.
생성자의 경우 오버로드 개념만 적용 가능하며 상속이나 재정의는 적용되지 않습니다.

네, 한 컨스트럭터를 다른 컨스트럭터에서 호출할 수 있습니다.하지만 거기에는 규칙이 있다.어떤 컨스트럭터에서 다른 컨스트럭터로 콜이 발신되는 경우

새 생성자 호출은 현재 생성자의 첫 번째 문이어야 합니다.

public class Product {
     private int productId;
     private String productName;
     private double productPrice;
     private String category;

    public Product(int id, String name) {
        this(id,name,1.0);
    }

    public Product(int id, String name, double price) {
        this(id,name,price,"DEFAULT");
    }

    public Product(int id,String name,double price, String category){
        this.productId=id;
        this.productName=name;
        this.productPrice=price;
        this.category=category;
    }
}

그래서 아래와 같은 것은 동작하지 않습니다.

public Product(int id, String name, double price) {
    System.out.println("Calling constructor with price");
    this(id,name,price,"DEFAULT");
}

또한 상속의 경우 서브클래스의 오브젝트가 생성되면 슈퍼클래스 생성자가 먼저 호출됩니다.

public class SuperClass {
    public SuperClass() {
       System.out.println("Inside super class constructor");
    }
}
public class SubClass extends SuperClass {
    public SubClass () {
       //Even if we do not add, Java adds the call to super class's constructor like 
       // super();
       System.out.println("Inside sub class constructor");
    }
}

따라서 이 경우 다른 컨스트럭터콜도 다른 스테이트먼트보다 먼저 선언됩니다.

이 키워드를 사용하면 같은 클래스 내의 다른 컨스트럭터에 있는1개의 컨스트럭터를 호출할 수 있습니다.

예:-

 public class Example {
   
      private String name;
   
      public Example() {
          this("Mahesh");
      }

      public Example(String name) {
          this.name = name;
      }

 }

쉬운 방법을 알려줄게

컨스트럭터에는 다음 두 가지 유형이 있습니다.

  1. 기본 생성자
  2. 매개 변수화된 생성자

예를 들어 설명하겠습니다.

class ConstructorDemo 
{
      ConstructorDemo()//Default Constructor
      {
         System.out.println("D.constructor ");
      }

      ConstructorDemo(int k)//Parameterized constructor
      {
         this();//-------------(1)
         System.out.println("P.Constructor ="+k);       
      }

      public static void main(String[] args) 
      {
         //this(); error because "must be first statement in constructor
         new ConstructorDemo();//-------(2)
         ConstructorDemo g=new ConstructorDemo(3);---(3)    
       }
   }                  

위의 예에서는 3종류의 콜을 나타내고 있습니다.

  1. 이것에 대한 this() 호출은 컨스트럭터의 첫 번째 문이어야 합니다.
  2. 이것은 Name less Object 입니다.기본 생성자를 자동으로 호출합니다.3 .그러면 파라미터화된 컨스트럭터가 호출됩니다.

참고: 이것은 생성자의 첫 번째 문이어야 합니다.

"this" 키워드를 사용하여 같은 클래스의 다른 생성자의 생성자를 만들 수 있습니다.예 -

class This1
{
    This1()
    {
        this("Hello");
        System.out.println("Default constructor..");
    }
    This1(int a)
    {
        this();
        System.out.println("int as arg constructor.."); 
    }
    This1(String s)
    {
        System.out.println("string as arg constructor..");  
    }

    public static void main(String args[])
    {
        new This1(100);
    }
}

출력 - arg 생성자로서의 문자열..기본 생성자...int는 arg 생성자로 지정됩니다.

다른 생성자에서 생성자를 호출하고 있습니다.

class MyConstructorDemo extends ConstructorDemo
{
    MyConstructorDemo()
    {
        this("calling another constructor");
    }
    MyConstructorDemo(String arg)
    {
        System.out.print("This is passed String by another constructor :"+arg);
    }
}

, 부모 하려면 , 를 사용합니다.super()

꽤 심플하다

public class SomeClass{

    private int number;
    private String someString;

    public SomeClass(){
        number = 0;
        someString = new String();
    }

    public SomeClass(int number){
        this(); //set the class to 0
        this.setNumber(number); 
    }

    public SomeClass(int number, String someString){
        this(number); //call public SomeClass( int number )
        this.setString(someString);
    }

    public void setNumber(int number){
        this.number = number;
    }
    public void setString(String someString){
        this.someString = someString;
    }
    //.... add some accessors
}

여기 약간의 추가 크레딧이 있습니다.

public SomeOtherClass extends SomeClass {
    public SomeOtherClass(int number, String someString){
         super(number, someString); //calls public SomeClass(int number, String someString)
    }
    //.... Some other code.
}

이게 도움이 됐으면 좋겠다.

복잡한 시공의 필요성을 커버하는 설계 패턴이 있습니다.간결하게 할 수 없는 경우에는 공장 방법이나 공장 클래스를 작성합니다.

최신 자바와 람다 추가를 통해 원하는 초기화 코드를 모두 사용할 수 있는 컨스트럭터를 쉽게 만들 수 있습니다.

class LambdaInitedClass {

   public LamdaInitedClass(Consumer<LambdaInitedClass> init) {
       init.accept(this);
   }
}

전화는...

 new LambdaInitedClass(l -> { // init l any way you want });

네, 다음 명령을 사용하여 한 컨스트럭터를 다른 컨스트럭터에서 호출할 수 있습니다.this()

class Example{
   private int a = 1;
   Example(){
        this(5); //here another constructor called based on constructor argument
        System.out.println("number a is "+a);   
   }
   Example(int b){
        System.out.println("number b is "+b);
   }

키워드를 사용하여 컨스트럭터에서 컨스트럭터를 호출할 수 있습니다.클래스에 여러 컨스트럭터를 쓸 때 코드 중복을 피하기 위해 다른 컨스트럭터를 호출할 수 있습니다.

Bellow는 컨스트럭터, getters() 및 setters()에 대한 다른 토픽을 설명하는 링크로, 2개의 컨스트럭터가 있는 클래스를 사용했습니다.설명과 예가 도움이 되길 바랍니다.

설정자 메서드 또는 생성자

키워드(같은 클래스에서 컨스트럭터를 호출해야 할 경우) 또는 키워드(슈퍼 클래스에서 컨스트럭터를 호출해야 할 경우)를 사용하여 다른 컨스트럭터를 호출할 수 있습니다.

단, 이러한 콜은 컨스트럭터의 첫 번째 스테이트먼트여야 합니다.이 제한을 극복하려면 다음 답변을 사용하십시오.

이 질문에는 많은 예가 있다는 것을 알지만, 제가 발견한 것은 제 아이디어를 공유하기 위해서입니다.컨스트럭터를 체인으로 하는 방법에는 두 가지가 있습니다.같은 클래스에서는 이 키워드를 사용할 수 있습니다.상속에서는 super 키워드를 사용해야 합니다.

    import java.util.*;
    import java.lang.*;

    class Test
    {  
        public static void main(String args[])
        {
            Dog d = new Dog(); // Both Calling Same Constructor of Parent Class i.e. 0 args Constructor.
            Dog cs = new Dog("Bite"); // Both Calling Same Constructor of Parent Class i.e. 0 args Constructor.

            // You need to Explicitly tell the java compiler to use Argument constructor so you need to use "super" key word
            System.out.println("------------------------------");
            Cat c = new Cat();
            Cat caty = new Cat("10");

            System.out.println("------------------------------");
            // Self s = new Self();
            Self ss = new Self("self");
        }
    }

    class Animal
    {
        String i;

        public Animal()
        {
            i = "10";
            System.out.println("Animal Constructor :" +i);
        }
        public Animal(String h)
        {
            i = "20";
            System.out.println("Animal Constructor Habit :"+ i);
        }
    }

    class Dog extends Animal
    {
        public Dog()
        {
            System.out.println("Dog Constructor");
        }
        public Dog(String h)
        {
            System.out.println("Dog Constructor with habit");
        }
    }

    class Cat extends Animal
    {
        public Cat()
        {
            System.out.println("Cat Constructor");
        }
        public Cat(String i)
        {
            super(i); // Calling Super Class Paremetrize Constructor.
            System.out.println("Cat Constructor with habit");
        }
    }

    class Self
    {
        public Self()
        {
            System.out.println("Self Constructor");
        }
        public Self(String h)
        {
            this(); // Explicitly calling 0 args constructor. 
            System.out.println("Slef Constructor with value");
        }
    }

이것은 텔레스코핑 컨스트럭터 안티 패턴 또는 컨스트럭터 체인이라고 불립니다.네, 물론 할 수 있어요.위의 많은 예를 볼 수 있는데, 2~3개의 컨스트럭터만 있으면 된다는 것을 안다면 괜찮다는 말을 덧붙이고 싶습니다.하지만 더 필요하시면 Builder 패턴과 같은 다른 디자인 패턴을 사용해보시기 바랍니다.예를 들어 다음과 같습니다.

 public Omar(){};
 public Omar(a){};
 public Omar(a,b){};
 public Omar(a,b,c){};
 public Omar(a,b,c,d){};
 ...

더 필요할 수도 있어요.이 경우 빌더 패턴이 훌륭한 솔루션이 될 수 있습니다.여기 기사가 있습니다.https://medium.com/@http:/design-http:/design-http:-2-the-http:/the-http:/the-http:/design-http:/the-http:/http:/http:/http:/http:/http:/h

예, 다른 생성자에서 생성자를 호출할 수 있습니다.예를 들어 다음과 같습니다.

public class Animal {
    private int animalType;

    public Animal() {
        this(1); //here this(1) internally make call to Animal(1);
    }

    public Animal(int animalType) {
        this.animalType = animalType;
    }
}

Java의 Constructor Chaining에서도 자세한 내용을 읽을 수 있습니다.

원래 Mirko Klemm의 앤서(Anser)에서 나온 것으로, 다음과 같은 질문에 대처하기 위해 약간 수정되었습니다.

완전성을 위해:또한 인스턴스 초기화 블록은 항상 실행되며 다른 생성자가 호출되기 전에 실행됩니다.클래스 정의 본문 어딘가에 있는 "{...}" 문 블록으로 구성되어 있습니다.두 개 이상 가질 수도 있습니다.호출할 수는 없지만 호출 메서드와 마찬가지로 생성자 간에 일부 코드를 재사용하려는 경우 "공유 생성자" 코드와 같습니다.

그래서 당신의 경우

{ 
  System.out.println("this is shared constructor code executed before the constructor");
  field1 = 3;
}

스태틱 멤버를 초기화하기 위한 "static" 버전도 있습니다. "static { ...}"

다음과 같은 방법이 좋습니다.

    class User {
        private long id;
        private String username;
        private int imageRes;

    public User() {
        init(defaultID,defaultUsername,defaultRes);
    }
    public User(String username) {
        init(defaultID,username, defaultRes());
    }

    public User(String username, int imageRes) {
        init(defaultID,username, imageRes);
    }

    public User(long id, String username, int imageRes) {
        init(id,username, imageRes);

    }

    private void init(long id, String username, int imageRes) {
        this.id=id;
        this.username = username;
        this.imageRes = imageRes;
    }
}

이것은 컨스트럭터 체인이라고 불립니다.생성자 체인은 현재 개체에 대해 다른 생성자에서 한 생성자를 호출하는 프로세스입니다.컨스트럭터 체인은 다음 두 가지 방법으로 수행할 수 있습니다.

1. 같은 클래스 내:이것은 같은 클래스2의 컨스트럭터에 대해 this() 키워드를 사용하여 실행할 수 있습니다.From base class: super() 키워드를 사용하여 기본 클래스에서 컨스트럭터를 호출합니다.

언급URL : https://stackoverflow.com/questions/285177/how-do-i-call-one-constructor-from-another-in-java

반응형