Why can't I refer to an instance method while explicitly invoking a constructor?
Solution 1
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.
Solution 2
See the Java Language Specification 8.8.7.1. This states that
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
orsuper
in any expression; otherwise, a compile-time error occurs.
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).
Solution 3
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
Solution 4
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.
Solution 5
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.
Koekiebox
Code loving, pattern poaching, methodology mending person trying to sustain social life... Not (Borat Style). SOreadytohelp
Updated on April 29, 2020Comments
-
Koekiebox about 4 years
Does anyone know why you can reference a
static
method in the first line of the constructor usingthis()
orsuper()
, but not a non-static method?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; } }
-
brady over 13 yearsThis is close, but not exact. Instances do exist when you are in a constructor, and you can invoke instance methods on them. But, you cannot do it until the super-class' constructor has completed. If you want to invoke them within your own constructor, that's fine, but the super class has to be finished.
-
Łukasz Rzeszotarski over 10 yearsThis is not an exact answer. Comment also not get the point totally because the question is not about calling super constructor but the constructor from the same class of course it is also because we need super constructor call first, but the answer and comment don't put it clearly.
-
gstackoverflow about 10 yearsWhat about this code? class ClassForTest{ ClassForTest(int k){ }; { method(); } ClassForTest(){ this(1); }; int method(){return 1;} }
-
gstackoverflow about 10 yearsor use this or super in any expression; otherwise, a compile-time error occurs please clarify
-
yeppe over 7 years@gstackoverflow when I modify your code like this I get this exception "Cannot refer to an instance field test while explicitly invoking a constructor" public class ClassForTest { int test=0; ClassForTest(int k) { } { method(); } ClassForTest() { this(test);//Cannot refer to an instance field test while explicitly invoking a constructor } int method() { return 1; } public static void main(String[] args) { new ClassForTest(); } }
-
dannail over 7 years@erickson what you said is true, but WHY? i mean, why is it designed that after the state variables can be referred to after superclass constructor invocation but not before? What's the rationale behind? You claimed instances do exist in constructor, so at what moment is the instance created?
-
dannail over 7 years@Marc that means instance is created in the heap after the explicit/implicit superclass constructor invocation is done, even though its initialization is not completed yet?
-
brady over 7 years@dannail The instance is created (i.e., space is allocated) first, then constructors run in order from
Object
to most-derived subclass. If methods could be invoked before the superclass' constructor completed, they could operate on partially initialized fields, which could violate expected conditions. -
Stephen C over 5 years@dannail - no, it doesn't. The heap object is created before any of the constructors is invoked.