Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Initialize field before super constructor runs?

In Java, is there any way to initialize a field before the super constructor runs?

Even the ugliest hacks I can come up with are rejected by the compiler:

class Base {     Base(String someParameter)     {         System.out.println(this);     } }  class Derived extends Base {     private final int a;      Derived(String someParameter)     {         super(hack(someParameter, a = getValueFromDataBase()));     }      private static String hack(String returnValue, int ignored)     {         return returnValue;     }      public String toString()     {         return "a has value " + a;     } } 

Note: The issue disappeared when I switched from inheritance to delegation, but I would still like to know.

like image 455
fredoverflow Avatar asked Mar 28 '13 12:03

fredoverflow


People also ask

Why must super () or this () Be the first statement in a constructor?

The Eclipse compiler says, Constructor call must be the first statement in a constructor . So, it is not stopping you from executing logic before the call to super() . It is just stopping you from executing logic that you can't fit into a single expression. There are similar rules for calling this() .

Do you have to initialize all variables in constructor?

It really depends on what member variables you have. If you provide a constructor and don't explicitly initialize a variable in the member initialization list, then it will be default initialized.

Can we initialize variable in constructor?

You can define a static field using the static keyword. If you declare a static variable in a class, if you haven't initialized it, just like with instance variables compiler initializes these with default values in the default constructor. Yes, you can also initialize these values using the constructor.

Should super be the first statement in constructor?

this or super Must Be the First Statement in the Constructor. Whenever we call a constructor, it must call the constructor of its base class. In addition, you can call another constructor within the class. Java enforces this rule by making the first call in a constructor be to this or super.


2 Answers

No, there is no way to do this.

According to the language specs, instance variables aren't even initialized until a super() call has been made.

These are the steps performed during the constructor step of class instance creation, taken from the link:

  1. Assign the arguments for the constructor to newly created parameter variables for this constructor invocation.
  2. If this constructor begins with an explicit constructor invocation (§8.8.7.1) of another constructor in the same class (using this), then evaluate the arguments and process that constructor invocation recursively using these same five steps. If that constructor invocation completes abruptly, then this procedure completes abruptly for the same reason; otherwise, continue with step 5.
  3. This constructor does not begin with an explicit constructor invocation of another constructor in the same class (using this). If this constructor is for a class other than Object, then this constructor will begin with an explicit or implicit invocation of a superclass constructor (using super). Evaluate the arguments and process that superclass constructor invocation recursively using these same five steps. If that constructor invocation completes abruptly, then this procedure completes abruptly for the same reason. Otherwise, continue with step 4.
  4. Execute the instance initializers and instance variable initializers for this class, assigning the values of instance variable initializers to the corresponding instance variables, in the left-to-right order in which they appear textually in the source code for the class. If execution of any of these initializers results in an exception, then no further initializers are processed and this procedure completes abruptly with that same exception. Otherwise, continue with step 5.
  5. Execute the rest of the body of this constructor. If that execution completes abruptly, then this procedure completes abruptly for the same reason. Otherwise, this procedure completes normally.
like image 167
Keppil Avatar answered Oct 14 '22 05:10

Keppil


Super constructor will run in any case, but since we are talking about the "ugliest hacks", we can take advantage of this

public class Base {     public Base() {         init();     }      public Base(String s) {     }      public void init() {     //this is the ugly part that will be overriden     } }  class Derived extends Base{      @Override     public void init(){         a = getValueFromDataBase();     } }  

I never suggest using these kind of hacks.

like image 22
Serkan Arıkuşu Avatar answered Oct 14 '22 05:10

Serkan Arıkuşu