Why can't I refer to an instance method while explicitly invoking a constructor?

26,529

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 or super 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.

Share:
26,529
Koekiebox
Author by

Koekiebox

Code loving, pattern poaching, methodology mending person trying to sustain social life... Not (Borat Style). SOreadytohelp

Updated on April 29, 2020

Comments

  • Koekiebox
    Koekiebox about 4 years

    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?

    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
    brady over 13 years
    This 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
    Łukasz Rzeszotarski over 10 years
    This 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
    gstackoverflow about 10 years
    What about this code? class ClassForTest{ ClassForTest(int k){ }; { method(); } ClassForTest(){ this(1); }; int method(){return 1;} }
  • gstackoverflow
    gstackoverflow about 10 years
    or use this or super in any expression; otherwise, a compile-time error occurs please clarify
  • yeppe
    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
    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
    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
    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
    Stephen C over 5 years
    @dannail - no, it doesn't. The heap object is created before any of the constructors is invoked.