首页 文章

如何在Java中调用另一个构造函数?

提问于
浏览
1928

是否可以从另一个(在同一个类中,而不是从子类中)调用构造函数?如果有,怎么样?什么是调用另一个构造函数的最佳方法(如果有几种方法可以做到)?

18 回答

  • 207

    是的,可以从另一个构建函数调用 . 但它有一个规则 . 如果从一个构造函数调用到另一个构造函数,那么

    新的构造函数调用必须是当前构造函数中的第一个语句

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

    因此,在这种情况下,还会在任何其他语句之前声明另一个构造函数调用 .

  • 2585

    您可以使用“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构造函数..

  • 4

    有些设计模式可以满足复杂结构的需求 - 如果不能简洁地完成,则可以创建工厂方法或工厂类 .

    使用最新的java和lambdas的添加,很容易创建一个构造函数,它可以接受你想要的任何初始化代码 .

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

    叫它......

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

    您可以通过this(...)关键字调用另一个构造函数(当您需要从同一个类调用构造函数时)或super(...)关键字(当您需要从超类调用构造函数时) .

    但是,这样的调用必须是构造函数的 first 语句 . 要 overcome 此限制,请使用this answer .

  • 4

    关键字 this 可用于从构造函数中调用构造函数,在为类编写多个构造函数时,有时您希望从另一个构造函数调用一个构造函数以避免重复代码 .

    Bellow是一个链接,我解释了关于构造函数和getters()和setters()的其他主题,我使用了一个带有两个构造函数的类 . 我希望解释和例子可以帮到你 .

    Setter methods or constructors

  • 8

    它被称为Telescoping Constructor反模式或构造函数链接 . 是的,你绝对可以 . 我在上面看到了很多例子,我想补充说,如果你知道你只需要两三个构造函数,那就可以了 . 但如果您需要更多,请尝试使用不同的设计模式,如Builder模式 . 例如:

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

    你可能需要更多 . 在这种情况下,Builder模式将是一个很好的解决方案 . 这是一篇文章,可能会有所帮助https://medium.com/@modestofiguereo/design-patterns-2-the-builder-pattern-and-the-telescoping-constructor-anti-pattern-60a33de7522e

  • 9

    I will tell you an easy way

    two 种类型的构造函数:

    • Default constructor

    • Parameterized constructor

    我将在一个例子中解释

    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种类型的呼叫

    • this()对此的调用必须是构造函数中的第一个语句

    • 这是Name less Object . 这会自动调用默认构造函数 . 3.这会调用参数化构造函数 .

    注意: this must be the first statement in the constructor.

  • 37

    正如大家已经说过的那样,你使用 this(…) ,这被称为显式构造函数调用 .

    However, keep in mind that 在这样一个显式的构造函数调用语句中 you may not refer to

    • 任何实例变量或

    • 任何实例方法或

    • 在此类或任何超类中声明的任何内部类,或

    • this

    • super .

    如JLS(§8.8.7.1)中所述 .

  • 3

    对的,这是可能的:

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

    要链接到特定的超类构造函数而不是同一类中的一个,请使用 super 而不是 this . 请注意 you can only chain to one constructorit has to be the first statement in your constructor body .

    另见this related question,这是关于C#但适用相同原则的地方 .

  • 3

    很简单

    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
    }
    

    现在这里有一些额外的小额信贷:

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

    希望这可以帮助 .

  • 186

    使用 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的调用必须是构造函数中的第一个调用,否则您将收到编译器错误 .

  • 24

    是的,任何数量的构造函数都可以出现在类中,并且可以使用 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");
        }
    }
    

    这称为构造函数重载 .
    请注意,对于构造函数,只有重载概念适用,而不是继承或覆盖 .

  • 8

    从另一个构造函数调用构造函数

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

    您也可以使用 super() 调用来调用父构造函数

  • 6

    是的,可以使用 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);
       }
    
  • 6

    [注意:我只想添加一个方面,我在其他答案中没有看到:如何克服这个()必须在第一行的要求的限制 . )

    在Java中的另一个构造函数可以通过 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;
    
      }
    
    }
    
  • 3

    当我需要从代码内部调用另一个构造函数(而不是在第一行)时,我通常使用这样的辅助方法:

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

    我知道这个问题有很多例子,但是我发现我在这里分享我的想法 . 链式构造函数有两种方法 . 在同一个类中,您可以使用此关键字 . 在继承中,您需要使用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");
            }
        }
    
  • 3

    在构造函数中,您可以使用 this 关键字来调用同一个类中的另一个构造函数 . 这样做被称为 explicit constructor invocation .

    这是另一个Rectangle类,其实现与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;
        }
    
    }
    

    该类包含一组构造函数 . 每个构造函数初始化一些或所有矩形的成员变量 .

相关问题