Comment appeler un constructeur à partir d'un autre en Java?

est-il possible d'appeler un constructeur d'un autre (dans la même classe, pas 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)?

1882
demandé sur James A. Rosen 2008-11-12 23:10:19

18 réponses

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 superclasses particulier au lieu d'un constructeur de la même classe, utiliser super au lieu de this . Notez que vous pouvez seulement enchaîner à un constructeur , et il doit être la première déclaration dans votre corps de constructeur .

Voir aussi cette question relative à la , ce qui est sur C#, mais où le même principes s'appliquent.

2538
répondu Jon Skeet 2017-05-23 12:34:53

par 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 un plus récemment préconisé l'approche de valueOf ou "de":

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
répondu Josh 2018-10-08 11:25:30

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

en Java, un autre constructeur de la même classe peut être appelé à partir d'un constructeur via this() . Note toutefois 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 this doit apparaître sur la première ligne semble comme une grande limitation, mais vous pouvez construire les arguments d'autres constructeurs via des 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
répondu Christian Fries 2016-02-10 02:53:05

quand j'ai besoin d'appeler un autre constructeur de l'intérieur du code (pas sur la première ligne), j'utilise habituellement 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 plus simples sur 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
répondu Kaamel 2013-04-23 23:12:24

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

Voici une autre classe de 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
répondu amila isura 2016-02-12 01:50:32

comme tout le monde l'a déjà dit, vous utilisez this(…) , qui est appelé un invocation explicite du constructeur .

Cependant, gardez à l'esprit que dans une telle déclaration d'invocation explicite du constructeur vous ne pouvez pas vous référer à

  • tout variables d'instance ou
  • tout les méthodes d'instance ou
  • toute classe classes intérieures déclarée dans cette classe ou dans toute superclasse, ou
  • this ou
  • super .

comme indiqué dans JLS (§8.8.7.1).

12
répondu olovb 2015-05-07 22:52:03

je vais vous dire un moyen facile

il y a deux types de constructeurs:

  1. constructeur par Défaut
  2. 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. ce() appeler cela doit être la première instruction du constructeur
  2. ici Nom Sans objet. cela appelle automatiquement le constructeur par défaut. 3.Cela appelle le constructeur Paramétrisé.

Note: ce doit être la première instruction du constructeur.

7
répondu 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() [s'il vous plaît ne pas confondre this() appel constructeur avec this mot-clé]. this() ou this(args) doit être la première ligne du 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, seulement la surcharge le concept est applicable et non héréditaire ou supérieur.

7
répondu Utsav 2018-06-21 05:46:06

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

cet appel de nouveau constructeur doit être la première déclaration dans le 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");
}

également, dans le cas d'héritage, lorsque la objet est créé, le constructeur super class 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 du constructeur est d'abord déclaré avant toute autre déclaration.

6
répondu S R Chaitanya 2018-08-22 17:30:59

vous pouvez un constructeur d'un autre constructeur de la même classe en utilisant" ce " mot-clé. 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 - string arg constructeur.. Constructeur par défaut.. int arg constructeur..

5
répondu ABHISHEK RANA 2015-11-27 19:01:24

appelant le constructeur 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 aussi appeler le constructeur parent en utilisant super() call

5
répondu Akshay Gaikwad 2017-03-03 09:50:18

Oui il est possible d'appeler un constructeur de l'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
répondu Akash Manngroliya 2018-04-11 02:20:50

le mot-clé ce peut être utilisé pour appeler un constructeur à partir d'un constructeur, lorsque vous écrivez plusieurs constructeurs pour une classe, Il ya des moments où vous souhaitez appeler un constructeur à partir d'un autre pour éviter le code dupliqué.

ci-dessous est un lien que j'explique 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.

Setter ou constructeurs

3
répondu S. Mayol 2017-05-23 12:02:58

il y a des modèles de conception qui couvrent le besoin de construction complexe - si cela ne peut pas être fait de façon succincte, créer une méthode d'usine ou une classe d'usine.

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
répondu 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
}

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

Espérons que cette aide.

2
répondu GetBackerZ 2017-11-21 14:03:51

je sais qu'il y a tant d'exemples de cette question mais ce que j'ai trouvé je le mets ici pour partager mon idée. il y a deux façons d'enchaî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
répondu Negi Rox 2018-02-13 14:05:23

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

cependant, un tel appel doit être le premier déclaration de votre constructeur. surmonter cette limitation, l'utilisation de cette réponse .

1
répondu John McClane 2018-07-29 01:14:04

il est appelé télescopique constructeur anti-modèle ou enchaînement constructeur. Oui, vous pouvez certainement le faire. Je vois beaucoup d'exemples ci-dessus et je tiens à ajouter que si vous savez que vous avez besoin de seulement deux ou trois constructeurs, il pourrait être ok. Mais si vous avez besoin de plus, s'il vous plaît essayer d'utiliser un modèle de conception différente comme Builder pattern. 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. Modèle de constructeur serait une excellente solution dans ce cas. Voici un article, il peut être utile https://medium.com/@modestofiguereo/design-patterns-2-the-builder-pattern-and-the-telescoping-constructor-anti-pattern-60a33de7522e

0
répondu Omar Faroque Anik 2018-06-06 19:36:32