为什么在显式调用构造函数时不能引用实例方法?

时间:2021-02-14 22:32:48

Does anyone know why you can reference a static method in the first line of the constructor using this() or super(), but not a non-static method?

有谁知道为什么在构造函数的第一行中用这个()或super()来引用静态方法,而不是一个非静态方法吗?

Consider the following working:

考虑以下工作:

public class TestWorking{
    private A a = null;
    public TestWorking(A aParam){
       this.a = aParam;
    }

    public TestWorking(B bParam)
    {
        this(TestWorking.getAFromB(bParam));
    }

    //It works because its marked static.
    private static A getAFromB(B param){
        A a = new A();
        a.setName(param.getName());
        return a;
    }
}

And the following Non-Working example:

下面是一个非工作的例子:

public class TestNotWorking{
    private A a = null;
    public TestNotWorking(A aParam){
       this.a = aParam;
    }

    public TestNotWorking(B bParam)
    {
        this(this.getAFromB(bParam));
    }

    //This does not work. WHY???
    private A getAFromB(B param){
        A a = new A();
        a.setName(param.getName());
        return a;
    }
}

6 个解决方案

#1


16  

Non-static methods are instance methods. This are only accessible in existing instance, and instance does not exist yet when you are in constructor (it is still under construction).

非静态方法是实例方法。这只能在现有实例中访问,并且在构造函数时实例还不存在(它仍在构建中)。

Why it is so? Because instance methods can access instance (non-static) fields, which can have different values in different instances, so it doesn't make sense to call such method on something else than existing, finished instance.

为什么它是如此?因为实例方法可以访问实例(非静态)字段,这些字段在不同的实例中可以有不同的值,因此在其他东西上调用这种方法是没有意义的。

#2


11  

See the Java Language Specification 8.8.7.1. This states that

参见Java语言规范8.8.7.1。这个州

An explicit constructor invocation statement in a constructor body may not refer to any instance variables or instance methods or inner classes declared in this class or any superclass, or use this or super in any expression; otherwise, a compile-time error occurs.

构造函数体中的显式构造函数调用语句可能不引用在该类或任何超类中声明的任何实例变量或实例方法或内部类,或在任何表达式中使用这个或super;否则,就会出现编译时错误。

This is because you can not call an instance method before the instance is created. By the way, it is possible to call an instance method later on in the constructor (although not a solution for you).

这是因为在创建实例之前,不能调用实例方法。顺便说一下,可以在构造函数中稍后调用实例方法(尽管不是针对您的解决方案)。

#3


1  

I think its's because final instance variables are not set yet (so you have no instance yet) and an instance method could access one. Whereas all static initialization has been done before the constructor call.

我认为这是因为最终的实例变量还没有设置(所以您还没有实例),并且实例方法可以访问一个。而所有的静态初始化都是在构造函数调用之前完成的。

Greetz, GHad

Greetz,盖德

#4


1  

because when you calling this or super in constructor your object is not constructed yet. (your instance is not initialized completely yet). so calling an instance method doesn't make scene.

因为当你在构造函数中调用这个或super时,你的对象还没有被构造。(您的实例尚未完全初始化)。因此,调用实例方法并不能构成场景。

#5


1  

TestNotWorking is not initialized at that point. The problem is: the first constructor (TestNotWorking(A aParam)) might call super() (internally it always does), meaning you would call a method before the constructor of the superclass is invoked. That's illegal.

在这一点上,TestNotWorking没有初始化。问题是:第一个构造函数(TestNotWorking(一个aParam))可能调用super()(在内部它总是这样),这意味着在调用父类的构造函数之前调用一个方法。这是非法的。

#6


0  

If a method is non-static then you must call it on an object.

如果一个方法是非静态的,那么您必须在对象上调用它。

In the second example you would need to create an object of class TestNotWorking and call getAFromB on that object.

在第二个示例中,您需要创建一个类TestNotWorking的对象,并在该对象上调用getAFromB。

Something like:

喜欢的东西:

object = new TestNotWorking();
object.getAFromB(bParam);

#1


16  

Non-static methods are instance methods. This are only accessible in existing instance, and instance does not exist yet when you are in constructor (it is still under construction).

非静态方法是实例方法。这只能在现有实例中访问,并且在构造函数时实例还不存在(它仍在构建中)。

Why it is so? Because instance methods can access instance (non-static) fields, which can have different values in different instances, so it doesn't make sense to call such method on something else than existing, finished instance.

为什么它是如此?因为实例方法可以访问实例(非静态)字段,这些字段在不同的实例中可以有不同的值,因此在其他东西上调用这种方法是没有意义的。

#2


11  

See the Java Language Specification 8.8.7.1. This states that

参见Java语言规范8.8.7.1。这个州

An explicit constructor invocation statement in a constructor body may not refer to any instance variables or instance methods or inner classes declared in this class or any superclass, or use this or super in any expression; otherwise, a compile-time error occurs.

构造函数体中的显式构造函数调用语句可能不引用在该类或任何超类中声明的任何实例变量或实例方法或内部类,或在任何表达式中使用这个或super;否则,就会出现编译时错误。

This is because you can not call an instance method before the instance is created. By the way, it is possible to call an instance method later on in the constructor (although not a solution for you).

这是因为在创建实例之前,不能调用实例方法。顺便说一下,可以在构造函数中稍后调用实例方法(尽管不是针对您的解决方案)。

#3


1  

I think its's because final instance variables are not set yet (so you have no instance yet) and an instance method could access one. Whereas all static initialization has been done before the constructor call.

我认为这是因为最终的实例变量还没有设置(所以您还没有实例),并且实例方法可以访问一个。而所有的静态初始化都是在构造函数调用之前完成的。

Greetz, GHad

Greetz,盖德

#4


1  

because when you calling this or super in constructor your object is not constructed yet. (your instance is not initialized completely yet). so calling an instance method doesn't make scene.

因为当你在构造函数中调用这个或super时,你的对象还没有被构造。(您的实例尚未完全初始化)。因此,调用实例方法并不能构成场景。

#5


1  

TestNotWorking is not initialized at that point. The problem is: the first constructor (TestNotWorking(A aParam)) might call super() (internally it always does), meaning you would call a method before the constructor of the superclass is invoked. That's illegal.

在这一点上,TestNotWorking没有初始化。问题是:第一个构造函数(TestNotWorking(一个aParam))可能调用super()(在内部它总是这样),这意味着在调用父类的构造函数之前调用一个方法。这是非法的。

#6


0  

If a method is non-static then you must call it on an object.

如果一个方法是非静态的,那么您必须在对象上调用它。

In the second example you would need to create an object of class TestNotWorking and call getAFromB on that object.

在第二个示例中,您需要创建一个类TestNotWorking的对象,并在该对象上调用getAFromB。

Something like:

喜欢的东西:

object = new TestNotWorking();
object.getAFromB(bParam);