Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

call to super() must be the first statement in constructor body

I'm writing the constructor of a LoginRequest class which extends a class called JsobObjectRequest (from the Volley framework in Android, but that's completely irrelevant to the question)

With this code :

 public LoginRequest(String username, String password, Response.Listener<JSONObject> responseListener, Response.ErrorListener errorListener) {
        Boolean hasCredentials=(username!=null && password!=null);
        int method=hasCredentials? Method.POST:Request.Method.GET;
        super(method, API_URL_LOGIN, null, responseListener, errorListener);

        this.username=username;
        this.password=password;

    }

I get the error: call to super() must be the first statement in constructor body

Instead, this code compiles just fine:

 public LoginRequest(String username, String password, Response.Listener<JSONObject> responseListener, Response.ErrorListener errorListener) {
        super((username!=null && password!=null)? Method.POST:Request.Method.GET, API_URL_LOGIN, null, responseListener, errorListener);

        this.username=username;
        this.password=password;

    }

But isn't it effectively the exact same thing? In both cases, a couple of trivial computation are made prior to calling the super constructor, based on the values of the parameters passed to the subclass constructor. Why shouldn't the compiler be able to compile the first example given that it can compile the second?

Is the calling-super-constructor-must-be-first-statement specification more simplistic than it would need to be, or am I missing something?

EDIT: this has been wrongly marked as duplicate of Why do this() and super() have to be the first statement in a constructor?. That question is much more generic and asks why super() have to be the first statement at all. The question here is why a case like the one I've posted would defeat those requirements (and it has been satisfactorily answered in this very question)

like image 604
matteo Avatar asked Oct 02 '14 20:10

matteo


People also ask

Why does call to super have to be first?

1 Answer. The parent class' constructor requires to be called before the subclass' constructor. This will assure you that if you call some methods on the parent class in your constructor, the parent class has already been set up correctly.

Does Super have to be first line in constructor?

Java requires that if you call this() or super() in a constructor, it must be the first statement.

Why call to this () must be the first statement in constructor?

this or super needs to be first statement in constructor so that child class constructor invokes parent class constructor first. This is required to initialize any variable in parent class before doing any thing in child constructor.

Where super () can be used within a constructor?

super is used to invoke a constructor of the immediate parent class. this refers to the instance and static variables of the current class. super refers to the instance and static variables of the immediate parent class. this can be used to return and pass as an argument in the context of a current class object.


1 Answers

Java enforces that the call to super (explicit or not) must be the first statement in the constructor. This is to prevent the subclass part of the object being initialized prior to the superclass part of the object being initialized.

In your case, you don't do anything but local "trivial computation", so all things considered, it would be okay. However, Java's compiler doesn't go to the level of determining whether statements before a call to super actually do any initialization. It just disallows all statements before super().

like image 68
rgettman Avatar answered Nov 15 '22 17:11

rgettman