Comment appeler un constructeur d'un autre en Java?


Est-il possible d'appeler un constructeur à partir d'un autre (dans la même classe, pas à partir d'une sous-classe)? Si oui, comment? Et quelle pourrait être la meilleure façon d'appeler un autre constructeur (s'il y a plusieurs façons de le faire)?

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

18 answers

Oui, c'est possible:

public class Foo {
    private int x;

    public Foo() {
        this(1);
    }

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

Pour enchaîner à un constructeur de superclasse particulier au lieu d'un dans la même classe, utilisez super au lieu de this. Notez que vous ne pouvez enchaîner qu'à un seul constructeur, et il doit s'agir de la première instruction de votre corps de constructeur.

Voir aussicette question connexe , qui concerne C# mais où les mêmes principes s'appliquent.

 2538
Author: Jon Skeet, 2017-05-23 12:34:53

En utilisant this(args). Le modèle préféré est de travailler du plus petit constructeur au plus grand.

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

Vous pouvez également utiliser une approche plus récemment préconisée de valueOf ou simplement "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;
 }
} 

Pour appeler une super classe, utilisez super(someValue). L'appel à super doit être le premier appel dans le constructeur ou, vous obtiendrez une erreur de compilation.

 201
Author: Josh, 2018-10-08 11:25:30

[Remarque: Je veux juste ajouter un aspect, que je n'ai pas vu dans les autres réponses: comment surmonter les limites de l'exigence que this() doit être sur la première ligne).]

En Java un autre constructeur de la même classe peut être appelée à partir d'un constructeur par this(). Notez cependant que this doit être sur la première ligne.

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

Que {[3] } doit apparaître sur la première ligne ressemble à une grande limitation, mais vous pouvez construire les arguments d'autres constructeurs via les méthodes statiques. Par exemple:

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, 2016-02-10 02:53:05

Lorsque j'ai besoin d'appeler un autre constructeur à l'intérieur du code (pas sur la première ligne), j'utilise généralement une méthode d'aide comme celle-ci:

class MyClass {
   int field;


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

Mais le plus souvent, j'essaie de le faire dans l'autre sens en appelant les constructeurs les plus complexes à partir des constructeurs les plus simples de la première ligne, dans la mesure du possible. Pour l'exemple ci-dessus

class MyClass {
   int field;

   MyClass(int value) {
      if (value<0)
         field = 0;
      else
         field = value;
   }
   MyClass() {
      this(0);
   }
}
 36
Author: Kaamel, 2013-04-23 23:12:24

Dans un constructeur, vous pouvez utiliser le mot-clé this pour appeler un autre constructeur dans la même classe. Cela s'appelle une invocation de constructeur explicite .

Voici une autre classe Rectangle, avec une implémentation différente de celle de la section Objets.

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

}

Cette classe contient un ensemble de constructeurs. Chaque constructeur initialise une partie ou la totalité des variables membres du rectangle.

 23
Author: amila isura, 2016-02-12 01:50:32

Comme tout le monde l'a déjà dit, vous utilisez this(…), qui s'appelle une invocation de constructeur explicite .

Cependant, gardez à l'esprit que dans une telle instruction d'invocation de constructeur explicite vous ne pouvez pas faire référence à

  • toute variable d'instance ou
  • toute méthode d'instance ou
  • toute classe interne déclarée dans cette classe ou toute superclasse, ou
  • this ou
  • super.

Comme indiqué dans JLS (§8.8.7.1).

 12
Author: olovb, 2015-05-07 22:52:03

Je vais vous dire un moyen facile

Il ya deux types de constructeurs:

  1. constructeur par Défaut
  2. le constructeur Paramétré

Je vais expliquer dans un exemple

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

Dans l'exemple ci-dessus, j'ai montré 3 types d'appel

  1. cet appel () à this doit être la première instruction du constructeur
  2. C'est un objet sans nom. cela appelle automatiquement le constructeur par défaut. 3.Cela appelle le Constructeur paramétré.

Remarque: cela doit être la première instruction du constructeur.

 7
Author: Shivanandam Sirmarigari, 2017-12-19 05:55:52

Oui, n'importe quel nombre de constructeurs peut être présent dans une classe et ils peuvent être appelés par un autre constructeur en utilisant this() [Veuillez ne pas confondre this() appel du constructeur avec this mot-clé]. this() ou this(args) devrait être la première ligne dans le constructeur.

Exemple:

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

C'est ce qu'on appelle la surcharge du constructeur.
Veuillez noter que pour le constructeur, seul le concept de surcharge est applicable et non l'héritage ou la substitution.

 7
Author: Utsav, 2018-06-21 05:46:06

Oui, il est possible d'appeler un constructeur à partir d'un autre. Mais il y a une règle à cela. Si un appel est effectué d'un constructeur à un autre, alors

ce nouvel appel de constructeur doit être la première instruction du constructeur actuel

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

Donc, quelque chose comme ci-dessous ne fonctionnera pas.

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

De plus, dans le cas de l'héritage, lorsque l'objet de la sous-classe est créé, le constructeur de la super classe est d'abord appelé.

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

Ainsi, dans ce cas aussi un autre appel de constructeur est d'abord déclaré avant toute autre instruction.

 6
Author: S R Chaitanya, 2018-08-22 17:30:59

Vous pouvez un constructeur d'un autre constructeur de la même classe en utilisant le mot-clé "this". Exemple -

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

Sortie - chaîne en tant que constructeur arg.. Constructeur par défaut.. int en tant que constructeur arg..

 5
Author: ABHISHEK RANA, 2015-11-27 19:01:24

Appeler le constructeur à partir d'un autre constructeur

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

Vous pouvez également appeler le constructeur parent en utilisantsuper() call

 5
Author: Akshay Gaikwad, 2017-03-03 09:50:18

Oui, il est possible d'appeler un constructeur à partir d'un autre avec l'utilisation de 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, 2018-04-11 02:20:50

Le mot-clé ceci peut être utilisé pour appeler un constructeur à partir d'un constructeur, lors de l'écriture de plusieurs constructeurs pour une classe, il y a des moments où vous souhaitez appeler un constructeur à partir d'un autre pour éviter le code en double.

Ci-dessous est un lien que j'explique un autre sujet sur le constructeur et getters() et setters() et j'ai utilisé une classe avec deux constructeurs. J'espère que les explications et les exemples vous aideront.

Méthodes ou constructeurs de Setter

 3
Author: S. Mayol, 2017-05-23 12:02:58

Il existe des modèles de conception qui couvrent le besoin de construction complexe - si cela ne peut pas être fait de manière succincte, créez une méthode factory ou une classe factory.

Avec le dernier java et l'ajout de lambdas, il est facile de créer un constructeur qui peut accepter n'importe quel code d'initialisation que vous désirez.

class LambdaInitedClass {

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

Appelez-le avec...

 new LambdaInitedClass(l -> { // init l any way you want });
 3
Author: Rodney P. Barbati, 2017-11-13 23:01:22

Assez simple

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
}

Maintenant, voici un petit crédit supplémentaire:

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

J'espère que cela aide.

 2
Author: GetBackerZ, 2017-11-21 14:03:51

Je sais qu'il y a tellement d'exemples de cette question, mais ce que j'ai trouvé, je le mets ici pour partager mon idée. il existe deux façons de chaîner le constructeur. Dans la Même classe, vous pouvez utiliser ce mot clé. dans l'Héritage, vous devez utiliser le mot clé 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");
        }
    }
 1
Author: Negi Rox, 2018-02-13 14:05:23

Vous pouvez appeler un autre constructeur via le this(...) mot-clé (quand vous avez besoin à appeler un constructeur de la même classe) ou de la super(...) mot-clé (lorsque vous devez appeler un constructeur à partir d'une superclasse).

Cependant, un tel appel doit être la première instruction de votre constructeur. De surmonter cette limitation, utiliser cette réponse.

 1
Author: John McClane, 2018-07-29 01:14:04

Il est appelé anti-modèle de constructeur télescopique ou chaînage de constructeur. Oui, vous pouvez certainement le faire. Je vois de nombreux exemples ci-dessus et je veux ajouter en disant que si vous savez que vous n'avez besoin que de deux ou trois constructeurs, cela pourrait être ok. Mais si vous avez besoin de plus, essayez d'utiliser un modèle de conception différent comme le modèle de constructeur. Comme par exemple:

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

Vous pourriez avoir besoin de plus. Le modèle de constructeur serait une excellente solution dans ce cas. Voici un article, il pourrait être utile https://medium.com/@modestofiguereo/design-patterns-2-the-builder-pattern-and-the-telescoping-constructor-anti-pattern-60a33de7522e

 0
Author: Omar Faroque Anik, 2018-06-06 19:36:32