Jak wywołać jeden konstruktor z drugiego w Javie?

Czy jest możliwe wywołanie konstruktora z innej (w ramach tej samej klasy, a nie z podklasy)? Jeśli tak, jak? A jaki może być najlepszy sposób na wywołanie innego konstruktora (jeśli jest na to kilka sposobów)?

Author: James A. Rosen, 2008-11-12

18 answers

Tak, jest to możliwe:

public class Foo {
    private int x;

    public Foo() {
        this(1);
    }

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

Aby połączyć się z określonym konstruktorem klasy nadrzędnej zamiast tego w tej samej klasie, użyj super zamiast this. Zauważ, że możesz połączyć się tylko z jednym konstruktorem , a musi to być pierwsze stwierdzenie w ciele konstruktora .

Zobacz także to powiązane pytanie , które dotyczy C#, ale gdzie obowiązują te same zasady.

 2538
Author: Jon Skeet,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:53

Za pomocą this(args). Preferowanym wzorcem jest praca od najmniejszego konstruktora do największego.

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

Można również użyć niedawno zalecanego podejścia valueOf lub po prostu "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;
 }
} 

Aby wywołać super klasę, użyj super(someValue). Wywołanie do super musi być pierwszym wywołaniem w konstruktorze, inaczej pojawi się błąd kompilatora.

 201
Author: Josh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-08 11:25:30

[Uwaga: chcę tylko dodać jeden aspekt, którego nie widziałem w innych odpowiedziach: jak przezwyciężyć ograniczenia wymogu, że to () musi być w pierwszej linii).]

W Javie inny konstruktor tej samej klasy może być wywołany z konstruktora za pomocą this(). Należy jednak pamiętać, że this musi znajdować się w pierwszej linii.

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

To this musi pojawić się w pierwszej linii wygląda na duże ograniczenie, ale argumenty innych konstruktorów można konstruować za pomocą metody statyczne. Na przykład:

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;

  }

}
 183
Author: Christian Fries,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-10 02:53:05

Kiedy muszę wywołać inny konstruktor z wewnątrz kodu (Nie w pierwszej linii), zwykle używam metody pomocniczej takiej jak Ta:

class MyClass {
   int field;


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

Ale najczęściej staram się zrobić to na odwrót, nazywając bardziej złożone konstruktory od prostszych z pierwszej linii, w miarę możliwości. Dla powyższego przykładu

class MyClass {
   int field;

   MyClass(int value) {
      if (value<0)
         field = 0;
      else
         field = value;
   }
   MyClass() {
      this(0);
   }
}
 36
Author: Kaamel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-23 23:12:24

Wewnątrz konstruktora, możesz użyć słowa kluczowego this do wywołania innego konstruktora w tej samej klasie. Jest to wywołanie jawnego konstruktora .

Oto kolejna klasa Rectangle, z inną implementacją niż ta w sekcji Obiekty.

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

}

Ta klasa zawiera zbiór konstruktorów. Każdy konstruktor inicjalizuje niektóre lub wszystkie zmienne składowe prostokąta.

 23
Author: amila isura,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-12 01:50:32

Jak już wszyscy mówili, używasz this(…), które nazywa sięjawnym wywołaniem konstruktora .

Należy jednak pamiętać, że w takiej jednoznacznej deklaracji wywołania konstruktora nie można odwoływać się do

  • dowolne zmienne instancji lub
  • dowolne metody instancji lub
  • dowolne klasy wewnętrzne zadeklarowane w tej klasie lub dowolnej superklasie, lub
  • this lub
  • super.

Zgodnie z JLS (§8.8.7.1).

 12
Author: olovb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-07 22:52:03

Powiem ci prosty sposób

Istnieją dwa typy konstruktorów :

  1. Default constructor
  2. Konstruktor Parametryzowany

Wyjaśnię w jednym przykładzie

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

W powyższym przykładzie pokazałem 3 rodzaje wywołania

  1. wywołanie this() musi być pierwszą instrukcją w konstruktorze
  2. to jest nazwa less Object. spowoduje to automatyczne wywołanie konstruktora domyślnego. 3.To nazywa Konstruktor parametryzowany.

Uwaga: to musi być pierwsze polecenie w konstruktorze.

 7
Author: Shivanandam Sirmarigari,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-19 05:55:52

Tak, dowolna liczba konstruktorów może być obecna w klasie i może być wywołana przez inny konstruktor używając this() [Proszę nie mylić this() wywołania konstruktora ze słowem kluczowym this]. this() lub this(args) powinny być pierwszą linią konstruktora.

Przykład:

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

Jest to znane jako przeciążenie konstruktora.
Należy pamiętać, że w przypadku konstruktora zastosowanie ma tylko koncepcja przeciążenia, a nie dziedziczenia lub nadpisywania.

 7
Author: Utsav,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-21 05:46:06

Tak możliwe jest wywołanie jednego konstruktora z drugiego. Ale jest w tym pewna zasada. Jeśli wywołanie jest wykonywane z jednego konstruktora do drugiego, to

to nowe wywołanie konstruktora musi być pierwszą instrukcją w bieżącym konstruktorze

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

Więc coś takiego jak poniżej nie zadziała.

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

Również, w przypadku dziedziczenia, kiedy obiekt sub-klasy jest tworzony, najpierw wywoływany jest konstruktor super klasy.

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

Tak więc, w tym przypadku również kolejne wywołanie konstruktora jest najpierw deklarowane przed jakimikolwiek innymi instrukcjami.

 6
Author: S R Chaitanya,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-22 17:30:59

Możesz utworzyć konstruktor z innego konstruktora tej samej klasy, używając słowa kluczowego "this". Przykład -

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

Wyjście - string as ARG constructor.. Konstruktor domyślny.. int jako konstruktor arg..

 5
Author: ABHISHEK RANA,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-27 19:01:24

Wywołanie konstruktora z innego konstruktora

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

Możesz również wywołać konstruktor nadrzędny używając super() call

 5
Author: Akshay Gaikwad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-03 09:50:18

Tak możliwe jest wywołanie jednego konstruktora z drugiego za pomocą 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);
   }
 5
Author: Akash Manngroliya,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-11 02:20:50

Słowo kluczowe to może być użyty do wywołania konstruktora z konstruktora, podczas pisania kilku konstruktorów dla klasy, są chwile, kiedy chcesz wywołać jeden konstruktor z drugiego, aby uniknąć duplikatów kodu.

Poniżej jest link, który wyjaśnia inny temat o constructor i getters () i setters () i użyłem klasy z dwoma konstruktorami. Mam nadzieję, że wyjaśnienia i przykłady wam pomogą.

Metody Settera lub konstruktory

 3
Author: S. Mayol,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:02:58

Istnieją wzorce projektowe, które pokrywają potrzebę skomplikowanej konstrukcji - jeśli nie można tego zrobić zwięźle, stwórz metodę fabryczną lub klasę fabryczną.

Dzięki najnowszej Javie i dodaniu lambda, łatwo jest stworzyć konstruktor, który zaakceptuje dowolny kod inicjalizacyjny.

class LambdaInitedClass {

   public LamdaInitedClass(Consumer<LambdaInitedClass> init) {
       init.accept(this);
   }
}
/ Align = "left" / ..
 new LambdaInitedClass(l -> { // init l any way you want });
 3
Author: Rodney P. Barbati,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-13 23:01:22

Całkiem proste

public class SomeClass{

    int number;
    String someString;

    public SomeClass(){
        number = 0;
    }

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

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

A teraz mała dodatkowa Zaliczka:

public SomeOtherClass extends SomeClass {
    public SomeOtherClass(int number, String someString){
         super(number, someString); //calls public SomeClass(int number, String someString)
    }
    //.... Some other code.
}
Mam nadzieję, że to pomoże.
 2
Author: GetBackerZ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-21 14:03:51

Wiem, że jest tak wiele przykładów tego pytania, ale to, co znalazłem, umieszczam tutaj, aby podzielić się moim pomysłem. istnieją dwa sposoby łańcucha konstruktora. W tej samej klasie możesz użyć tego słowa kluczowego. w dziedziczeniu musisz użyć super słowa kluczowego.

    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");
        }
    }
 1
Author: Negi Rox,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-13 14:05:23

Możesz wywołać inny konstruktor poprzez this(...) słowo kluczowe (gdy trzeba wywołać konstruktor z tej samej klasy) lub super(...) słowo kluczowe (gdy trzeba wywołać konstruktor z klasy nadrzędnej).

Jednak takie wywołanie musi być pierwszą instrukcją twojego konstruktora. Abyprzezwyciężyć to ograniczenie, użyjtej odpowiedzi .

 1
Author: John McClane,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-29 01:14:04

Nazywa się to teleskopowym konstruktorem anty-pattern lub konstruktorem łańcuchowym. Tak, zdecydowanie możesz to zrobić. Widzę wiele przykładów powyżej i chcę dodać, że jeśli wiesz, że potrzebujesz tylko dwóch lub trzech konstruktorów, może być ok. Ale jeśli potrzebujesz więcej, spróbuj użyć innego wzoru projektowego, takiego jak wzór budowniczego. Jak na przykład:

 public Omar(){};
 public Omar(a){};
 public Omar(a,b){};
 public Omar(a,b,c){};
 public Omar(a,b,c,d){};
 ...
Możesz potrzebować więcej. Wzór konstruktora byłby świetnym rozwiązaniem w tym przypadku. Oto artykuł, może być pomocny https://medium.com/@modestofiguereo/design-patterns-2-the-builder-pattern-and-the-telescoping-constructor-anti-pattern-60a33de7522e
 0
Author: Omar Faroque Anik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-06 19:36:32