Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/376.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么我不能调用非静态方法作为构造函数中的参数? 有效代码1:_Java_Methods_Constructor_Instance - Fatal编程技术网

Java 为什么我不能调用非静态方法作为构造函数中的参数? 有效代码1:

Java 为什么我不能调用非静态方法作为构造函数中的参数? 有效代码1:,java,methods,constructor,instance,Java,Methods,Constructor,Instance,我的解决方案-我可以在构造函数中调用非静态方法 无效代码 编译错误: java: cannot reference this before supertype constructor has been called 有效代码2: 有效代码3: 这种行为对我来说很奇怪 你能共同解释一下吗 更新 据我所知,编译器合并init块如下: constructor(){ super(); nonStaticInitBlock; remain constructor code; } 我不

我的解决方案-我可以在构造函数中调用非静态方法

无效代码 编译错误:

java: cannot reference this before supertype constructor has been called
有效代码2: 有效代码3: 这种行为对我来说很奇怪

你能共同解释一下吗

更新 据我所知,编译器合并init块如下:

constructor(){
   super();
   nonStaticInitBlock;
   remain constructor code;
}
我不明白为什么我不能使用这个调用作为构造函数的参数

编辑
实例初始值设定项在最后一次构造函数调用后被调用Sotirios Delimanolis 6月1日17:17

@索蒂里奥斯,你错了

研究此代码:

public class Order {
    { 
        System.out.println("initializer!");
    } 
    Order(){ 
        System.out.println("constructor");
    } 
    public static void main(String [] args){
        new Order(); 
    }
}
结果:

initializer!
constructor
(由于先前的答案不正确而更改)

我相信答案在于编译器给你的错误:

java: cannot reference this before supertype constructor has been called
                                   ^^^^^^^^^
查看JLS第12.5节:

如果此构造函数以同一类中另一个构造函数的显式构造函数调用(§8.8.7.1)开始(使用
this
),则使用相同的五个步骤递归地评估参数和该构造函数调用的过程

在JLS 8.8.7中:

构造函数体中的显式构造函数调用语句不能引用该类或任何超类中声明的任何实例变量、实例方法或内部类,也不能在任何表达式中使用this或super;否则,将发生编译时错误

因此,为了运行第二个清单中的代码,
method()
需要在进入
this()
主体之前进行评估。但是,规范禁止这样做,因为对象的状态可能尚未完全初始化,例如,对于其构造函数设置子类型继承的某些状态的类型的子类

class ClassForTest{
    ClassForTest(int k){
    };
    ClassForTest(){
         this(method());
    };
    int method(){return 1;}
}
现在
method()
是一个实例方法,这意味着需要对ClassForTest类型的对象调用它。上述代码本质上意味着

ClassForTest(){
             this(this.method());
        };
并且您不能在构造函数中调用this.something(),因为只有在调用了超类的所有构造函数之后才会创建对象。所以这是不允许的


其中,对于静态方法,您不必等到创建对象,即调用所有超类构造函数。所以它是允许的。

有效代码3如何?@gstackoverflow初始化块在调用
this()
和/或
super()
后运行,所以该块是OKhm,有趣的顺序@gstackoverflow如果您想了解更多信息,请查看JLS第12.4节和第12.5节,其中指定了初始化类、接口和对象的确切步骤。我知道这个顺序是正确的,但它已经足够混乱了。有效代码3呢?方法调用发生在构造函数调用之前!!!!在重复的问题中,没有解释有效的代码3实例初始值设定项是在上次构造函数调用后调用的。公共类顺序{{公共类顺序{{System.out.println(“初始值设定项!”;}顺序(){System.out.println(“构造函数”);}公共静态void main(字符串[]args){新顺序()}System.out.println(“初始值设定项!”);}Order(){System.out.println(“构造函数”);}公共静态void main(字符串[]args){new Order();}}@Sotirios Delimanolis您错了我可以在初始化块中引用此指针。此块在构造函数之前执行,因此对象未被设计,但我可以调用它。
initializer!
constructor
java: cannot reference this before supertype constructor has been called
                                   ^^^^^^^^^
class ClassForTest{
    ClassForTest(int k){
    };
    ClassForTest(){
         this(method());
    };
    int method(){return 1;}
}
ClassForTest(){
             this(this.method());
        };