下面的程序非常困惑关于构造函数调用非常新的Java,请清楚地解释这个概念


   class Machine {
     private String name;
     private int code;
     public Machine(){
        this("back",1);
        System.out.println("constructor working!!!!");        
     }
     public Machine(String name){
        this("jick",1);
        System.out.println("Second constructor!!!");
        this.name = name;
     }
     public Machine(String name, int code){
      // this(); compile time error
       //this("back"); //compile time error
           System.out.println("third constructor");
           this.name = name;
            this.code = code;
     }
   }
   public class Constructoroverloading{
     public static void main(String[] args) {
      //Machine m1 = new Machine();
      // Machine m2 = new Machine("shruthi");
      // Machine m3 = new Machine("shruthi",20);
    }
 }

这是我写的程序,我怀疑为什么我的第三个构造函数无法调用第一个和第二个构造函数。 当我尝试调用第一个或第二个构造函数时,编译器显示递归调用错误,我并没有真正清楚地理解这个概念以及为什么我得到编译时错误。

假设您的代码已编译,看起来像

 public Machine(){
    this("foo");
    ...
 }
 public Machine(String name){
    this();
    ...
 }

现在,如果我们调用这些构造函数之一会发生什么?让我们逐步完成此代码。我们将从new Machine("enigma")开始:

  1. 调用Machine(String name)
    1. 在第一条指令中,它调用this();
    2. 所以正在执行Machine()中的代码
      1. 在第一条指令中调用this("foo");
      2. 所以再次调用Machine(String name)
        1. 在内部再次在第一条指令中调用this();
        2. 所以再次调用Machine()

。(依此类推,直到堆栈溢出(。无法逃避这个循环,因为每个构造函数中的第一个指令总是从该循环调用其他构造函数,这会阻止我们添加任何可以解决此问题的代码。
因此,由于编译器看到没有适当的停止点,它会阻止您编译此类代码,直到您纠正此错误。

问题是:

1(你有三个不同的构造函数(确定(

2(前两个各调用第三个(OK(

。但。。。

3(第三个构造函数不能调用前两个中的任何一个...因为那样它就会有效地调用自己。 这称为无限递归。

下面是代码的工作示例:

/*
 * Sample output:
 *   Machine(name, code) constructor: name=back, code=1
 *   default constructor: name=back, code=1
 *   Machine(name, code) constructor: name=jick, code=1
 *   Machine(name) constructor@1: name=shruthi, code=1
 *   Machine(name) constructor@2: name=shruthi, code=1
 *   Machine(name, code) constructor: name=shruthi, code=20
 */
   class Machine {
     private String name = "default";
     private int code = 100;
     public Machine(){
        this("back",1);  // Note: the default constructor calls "Machine(name, code)"
        System.out.println("default constructor: name=" + name + ", code=" + code);        
     }
     public Machine(String name){
        this("jick",1);  // // Note: this constructor ALSO calls "Machine(name, code)"
        System.out.println("Machine(name) constructor@1: name=" + name + ", code=" + code);        
        this.name = name;
        System.out.println("Machine(name) constructor@2: name=" + name + ", code=" + code);        
     }
     public Machine(String name, int code){
        //this(); // error: recursive constructor invocation
        //this("back"); // error: recursive constructor invocation
        //either of these two statements would *call itself infinitely*
        this.name = name;
        this.code = code;
        System.out.println("Machine(name, code) constructor: name=" + name + ", code=" + code);        
     }
   }
   public class Constructoroverloading{
     public static void main(String[] args) {
       Machine m1 = new Machine();
       Machine m2 = new Machine("shruthi");
       Machine m3 = new Machine("shruthi",20);
     }
   }

相关内容

最新更新