views:

288

answers:

3

I get a NullPointerException calling a Superclass Method in Subclass Inner Class Constructor... What's the Deal?


In my application's main class (subclass of Application), I have a public inner class that simply contains 3 public string objects. In the parent class I declare an object of that inner class.

public class MainApplication extends Application {
    public class Data {
        public String x;
        public String y;
        public String z;
    }

    private Data data;

    MainApplication() {
        data = new Data()

        data.x = SuperClassMethod();
    }
}

After I instantiate the object in the constructor, I get a runtime error when I try to assign a value in the inner class with a superclass method.

Any idea what's up here?? Can you not call superclass methods in the subclass constructor?

** Edit ** Original question was about inner class member assignment in outer class constructor. Turned out the issue was with calling a superclass method in the class's constructor. It was giving me a null pointer exception. Thus, the question has changed.

A: 

Try making your innerclass static:

public static class Data {

that way it isn't tied to the MainApplication instance.

update

From your comment it seems that you mean that the Application part of the object-under-construction is not initialised correctly when methods on it are called.

Calling methods of objects that are being constructed from their own constructor can result in unexpected behaviour as the objects are not initialised consistently until the constructor finishes. That said, it is possible that adding an explicit call to the super constructor fixes your dependency:

MainApplication() {
    super();

    data = new Data();
rsp
-1 What's wrong with being tied to the `MainApplication` instance, since it is created in the `MainApplication` constructor, the instance does exists (unless Dalvik works differently which I don't think so )
OscarRyz
@Oscar, what is wrong is that while in the constructor `MainApplication` is not constructed fully which means that the implicit reference between the `Data` instance and its parent object still refers to an object that is possibly inconsistent. Kinda like when you call your own methods from your constructor.
rsp
@rsp: mmhh that's not how java works. Anyway, that isn't the problem here :) Peace
OscarRyz
You say that's not how java works (and I would have thought the same) ... but I had issues calling a superclass method in the subclass constructor... I'll buy this until I get a better explanation.
stormin986
+1  A: 

So I added a semicolon, an empty base class and a main.

class Application {
}

public class MainApplication extends Application {
    public class Data {
        public String x;
        public String y;
        public String z;
    }

    private Data data;

    MainApplication() {
        data = new Data();

        data.x = "String";
    }

    public static void main(String[] args) {
        new MainApplication();
    }
}

Works for me! (Although I don't have an Android platform.)

(Was the semicolon a copy-and-paste error? Or was this not the original code?)

Tom Hawtin - tackline
+1 and the mind reading badge if this is the correct answer. Since stormin986 is not posting the actual error ( which in this case would be: *"Good programmer expected"* ) we can't know if this was the correct answer or not.
OscarRyz
Those problems would rather have produced a compiletime error.
BalusC
A: 

A non-static inner class such as Data class requires an instance of MainApplication to be valid. During the constructor MainApplication is not fully formed and so cannot be used. As rsp said, making Data static should get round this problem.

DJClayworth
The code as almost posted does work.
Tom Hawtin - tackline
-1 Since he instantiating the inner class `Data` inside the constructor of the outer class, the instance already exists. This answer is misleading.
OscarRyz
An instance is not considered complete until its constructor has completed. Even if it can be made to work, it's extremely bad practice to do what's being done here.
DJClayworth