etc./StackOverFlow

Java에서 하나의 생성자를 다른 생성자에서 어떻게 호출합니까?

청렴결백한 만능 재주꾼 2021. 11. 24. 06:13
반응형

질문자 :ashokgelal


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



예, 가능합니다:

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

같은 클래스에 있는 생성자 대신 특정 슈퍼클래스 생성자에 연결하려면 this 대신 super 를 사용하세요. 하나의 생성자에만 연결할 수 있으며 생성자 본문의 첫 번째 명령문이어야 합니다 .

C#에 관한 것이지만 동일한 원칙이 적용되는 이 관련 질문 도 참조하십시오.


Jon Skeet

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; } }

또한 최근에 옹호된 valueOf 또는 "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에 대한 호출은 생성자의 첫 번째 호출이어야 하며 그렇지 않으면 컴파일러 오류가 발생합니다.


Community Wiki

[ 참고: 다른 답변에서 볼 수 없었던 한 가지 측면을 추가하고 싶습니다. 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; } }

Christian Fries

코드 내부에서(첫 번째 줄이 아닌) 다른 생성자를 호출해야 할 때 일반적으로 다음과 같은 도우미 메서드를 사용합니다.

 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); } }

Kaamel

생성자 내에서 this 키워드를 사용하여 동일한 클래스의 다른 생성자를 호출할 수 있습니다. 이렇게 하는 것을 명시적 생성자 호출 이라고 합니다.

다음은 Objects 섹션의 구현과 다른 구현을 가진 또 다른 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; } }

이 클래스에는 생성자 세트가 포함되어 있습니다. 각 생성자는 사각형의 멤버 변수 일부 또는 전체를 초기화합니다.


amila isura

모두가 이미 말했듯 이 명시적 생성자 호출 이라고 하는 this(…) 를 사용합니다.

그러나 이러한 명시적 생성자 호출 문 내에서 다음을 참조할 수 없음 을 명심하십시오.

  • 모든 인스턴스 변수 또는
  • 모든 인스턴스 메서드 또는
  • 이 클래스나 슈퍼 클래스에 선언된 모든 내부 클래스, 또는
  • this 또는
  • super .

JLS(§8.8.7.1)에 명시된 대로.


olovb

예, 클래스에는 생성자가 얼마든지 있을 수 있으며 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"); } }

이것을 생성자 오버로딩이라고 합니다.
생성자의 경우 오버로딩 개념만 적용되며 상속 또는 재정의가 적용되지 않습니다.


Utsav

예, 하나의 생성자를 다른 생성자에서 호출할 수 있습니다. 그러나 거기에는 규칙이 있습니다. 한 생성자에서 다른 생성자로 호출이 이루어지면

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

 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"); } }

따라서 이 경우 다른 생성자 호출도 먼저 다른 명령문보다 먼저 선언됩니다.


S R Chaitanya

내가 쉬운 방법을 알려줄게

생성자에는 두 가지 유형이 있습니다.

  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. 이름 없는 개체입니다. 이것은 자동으로 기본 생성자를 호출합니다. 3. 이것은 Parameterized 생성자를 호출합니다.

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


Shivanandam

"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 생성자로..


ABHISHEK RANA

다른 생성자에서 생성자 호출

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

super() 호출을 사용하여 상위 생성자를 호출할 수 있습니다.


Akshay Gaikwad

꽤 간단하다

 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. }

도움이 되었기를 바랍니다.


GetBackerZ

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); }

Akash Manngroliya

this 키워드는 생성자에서 생성자를 호출하는 데 사용할 수 있습니다. 클래스에 대해 여러 생성자를 작성할 때 중복 코드를 피하기 위해 한 생성자를 다른 생성자에서 호출하려는 경우가 있습니다.

Bellow는 생성자와 getters() 및 setters()에 대한 다른 주제를 설명하는 링크이며 두 개의 생성자가 있는 클래스를 사용했습니다. 설명과 예시가 도움이 되었으면 합니다.

Setter 메서드 또는 생성자


S. Mayol

복잡한 구성의 필요성을 다루는 디자인 패턴이 있습니다. 간결하게 수행할 수 없는 경우 팩토리 메소드 또는 팩토리 클래스를 만드십시오.

최신 Java 및 람다 추가로 원하는 초기화 코드를 수락할 수 있는 생성자를 쉽게 만들 수 있습니다.

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

로 부르세요...

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

Rodney P. Barbati

이 질문에 대한 예가 너무 많다는 것을 알고 있지만 내가 찾은 것은 내 아이디어를 공유하기 위해 여기에 둡니다. 생성자를 연결하는 두 가지 방법이 있습니다. 같은 클래스에서 이 키워드를 사용할 수 있습니다. 상속에서는 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 ie 0 args Constructor. Dog cs = new Dog("Bite"); // Both Calling Same Constructor of Parent Class ie 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"); } }

Negi Rox

Telescoping Constructor 안티 패턴 또는 생성자 체이닝이라고 합니다. 예, 확실히 할 수 있습니다. 위의 예를 많이 보았고 생성자가 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/@modestofiguereo/design-patterns-2-the-builder-pattern-and-the-telescoping-constructor-anti-pattern-60a33de7522e


Omar Faroque Anik

this(...) 키워드(같은 클래스에서 생성자를 호출해야 하는 경우) 또는 super(...) 키워드(수퍼 클래스에서 생성자를 호출해야 하는 경우)를 통해 다른 생성자를 호출할 수 있습니다.

그러나 이러한 호출은 생성자 의 첫 번째 명령문이어야 합니다. 이 한계를 극복 하려면 이 답변을 사용하십시오.


John McClane

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

 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에서 자세한 내용을 읽을 수도 있습니다.


Soni Vashisht

원래 Mirko Klemm의 anser에서 가져온 것으로 다음 질문을 해결하기 위해 약간 수정되었습니다.

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

그래서 귀하의 경우

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

정적 멤버를 초기화하는 "정적" 버전도 있습니다. "static { ... }"


rogerdpack

이 키워드를 사용하여 동일한 클래스 내의 다른 생성자에서 하나의 생성자를 호출할 수 있습니다.

예시 :-

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

Anil Nivargi

나는 이 방법을 선호한다:

 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; } }

ansh sachdeva

이를 생성자 연결이라고 합니다. 생성자 연결은 현재 개체와 관련하여 다른 생성자에서 하나의 생성자를 호출하는 프로세스입니다. 생성자 연결은 두 가지 방법으로 수행할 수 있습니다.

1.동일 클래스 내: 동일한 클래스의 생성자에 대해 this() 키워드를 사용하여 수행할 수 있습니다. 2. 기본 클래스에서: super() 키워드를 사용하여 기본 클래스에서 생성자를 호출합니다.


keshari abeysinghe

출처 : http:www.stackoverflow.com/questions/285177/how-do-i-call-one-constructor-from-another-in-java

반응형