¿Cómo llamo a un constructor desde otro en Java?


¿Es posible llamar a un constructor desde otro (dentro de la misma clase, no desde una subclase)? En caso afirmativo, ¿cómo? ¿Y cuál podría ser la mejor manera de llamar a otro constructor (si hay varias maneras de hacerlo)?

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

18 answers

Sí, es posible:

public class Foo {
    private int x;

    public Foo() {
        this(1);
    }

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

Para encadenar a un constructor de superclase en particular en lugar de uno en la misma clase, use super en lugar de this. Tenga en cuenta que solo puede encadenar a un constructor, y tiene que ser la primera instrucción en su cuerpo constructor.

Ver también esta pregunta relacionada, que trata de C# pero donde se aplican los mismos principios.

 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:34:53

Usando this(args). El patrón preferido es trabajar desde el constructor más pequeño hasta el más grande.

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

También puede utilizar un enfoque más recientemente defendido de valueOf o simplemente "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;
 }
} 

Para llamar a una superclase, use super(someValue). La llamada a super debe ser la primera llamada en el constructor o obtendrá un error de compilador.

 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-10-08 11:25:30

[Nota: Solo quiero añadir un aspecto, que no vi en las otras respuestas: cómo superar las limitaciones del requisito de que este() tiene que estar en la primera línea).]

En Java se puede llamar a otro constructor de la misma clase desde un constructor a través de this(). Tenga en cuenta, sin embargo, que this tiene que estar en la primera línea.

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 tiene que aparecer en la primera línea parece una gran limitación, pero puede construir los argumentos de otros constructores a través de métodos estáticos. Por ejemplo:

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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-10 02:53:05

Cuando necesito llamar a otro constructor desde dentro del código (no en la primera línea), normalmente uso un método helper como este:

class MyClass {
   int field;


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

Pero la mayoría de las veces trato de hacerlo al revés llamando a los constructores más complejos de los más simples en la primera línea, en la medida de lo posible. Para el ejemplo anterior

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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-23 23:12:24

Dentro de un constructor, puedes usar la palabra clave this para invocar a otro constructor de la misma clase. Hacer esto se llama una invocación explícita del constructor .

Aquí hay otra clase Rectangle, con una implementación diferente de la de la sección Objects.

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

}

Esta clase contiene un conjunto de constructores. Cada constructor inicializa algunas o todas las variables miembro del rectángulo.

 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-12 01:50:32

Como todo el mundo ya ha dicho, se usa this(…), que se llama invocación explícita del constructor.

Sin embargo, tenga en cuenta que dentro de una declaración explícita de invocación del constructor no puede referirse a

  • cualquier variable de instancia o
  • cualquier método de instancia o
  • any inner classes declared in this class or any superclass, or {[17]]}
  • this o
  • super.

Como se indica en 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-07 22:52:03

Te lo diré de una manera fácil

Hay dos tipos de constructores:

  1. Constructor predeterminado
  2. Constructor parametrizado

Voy a explicar en un Ejemplo

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

En el ejemplo anterior mostré 3 tipos de llamadas

  1. esta llamada () a esto debe ser la primera declaración en constructor
  2. Este es un Objeto sin nombre. esto llama automáticamente al constructor predeterminado. 3.Esto llama a la Constructor parametrizado.

Nota: esta debe ser la primera instrucción en el constructor.

 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-19 05:55:52

Sí, cualquier número de constructores puede estar presente en una clase y pueden ser llamados por otro constructor usando this() [Por favor, no confunda this() llamada al constructor con this palabra clave]. this() o this(args) debe ser la primera línea en el constructor.

Ejemplo:

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

Esto se conoce como sobrecarga del constructor.
Tenga en cuenta que para constructor, solo se aplica el concepto de sobrecarga y no la herencia o la sobreescritura.

 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-21 05:46:06

Sí es posible llamar a un constructor desde otro. Pero hay una regla. Si se realiza una llamada de un constructor a otro, entonces

esa nueva llamada al constructor debe ser la primera instrucción en el constructor actual

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

Por lo tanto, algo como abajo no funcionará.

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

También, en el caso de la herencia, cuando se crea el objeto de subclase, se llama primero al constructor de superclase.

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

Así, en este caso también otra llamada al constructor se declara primero antes que cualquier otra instrucción.

 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-22 17:30:59

Puede un constructor de otro constructor de la misma clase usando la palabra clave "this". Ejemplo -

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

Salida - string como constructor arg.. Constructor predeterminado.. int como constructor de 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-27 19:01:24

Llamando al constructor desde otro constructor

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

También puedes llamar al constructor padre usando 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-03 09:50:18

Sí es posible llamar a un constructor desde otro con el uso 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,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-11 02:20:50

La palabra clave esto se puede usar para llamar a un constructor desde un constructor, al escribir varios constructores para una clase, hay momentos en los que le gustaría llamar a un constructor desde otro para evitar código duplicado.

A continuación hay un enlace en el que explico otro tema sobre constructor y getters() y setters() y utilicé una clase con dos constructores. Espero que las explicaciones y ejemplos te ayuden.

Métodos de setter o constructores

 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:02:58

Hay patrones de diseño que cubren la necesidad de una construcción compleja; si no se puede hacer sucintamente, cree un método de fábrica o una clase de fábrica.

Con el último java y la adición de lambdas, es fácil crear un constructor que pueda aceptar cualquier código de inicialización que desee.

class LambdaInitedClass {

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

Llámalo con...

 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-13 23:01:22

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

Ahora aquí hay un pequeño crédito extra:

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

Espero que esto ayude.

 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-21 14:03:51

Sé que hay muchos ejemplos de esta pregunta, pero lo que encontré lo estoy poniendo aquí para compartir mi Idea. hay dos maneras de encadenar constructor. En la misma clase se puede utilizar esta palabra clave. en Herencia, necesitas usar súper palabra clave.

    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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-13 14:05:23

Puede llamar a otro constructor a través del this(...) keyword (cuando necesita llamar a un constructor de la misma clase) o el super(...) palabra clave (cuando necesitas llamar a un constructor desde una superclase).

Sin embargo, tal llamada debe ser la primera declaración de su constructor. Parasuperar esta limitación, useesta respuesta .

 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-29 01:14:04

Se llama Telescoping Constructor anti-patrón o encadenamiento constructor. Sí, definitivamente puedes hacerlo. Veo muchos ejemplos anteriores y quiero agregar diciendo que si sabes que solo necesitas dos o tres constructores, podría estar bien. Pero si necesita más, intente usar un patrón de diseño diferente como el patrón del constructor. Como por ejemplo:

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

Es posible que necesite más. Patrón constructor sería una gran solución en este caso. Aquí hay un artículo, podría ser útil 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-06 19:36:32