views:

92

answers:

6

Hi,

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(TestNotWorking.getAFromB(bParam));
    }

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

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.

amorfis
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.
erickson
+1  A: 

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

GHad
+1  A: 

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.

mohammad shamsi
A: 

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.

Something like:

object = new TestNotWorking();
object.getAFromB(bParam);
Florin
+1  A: 

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.

Thomas Mueller
+2  A: 

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 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).

Marc