According to the SCJP6 (Page 507) i found that instance variables are assigned default values before the superclass constructors complete, i tried an example in Debugg mode but i saw that the super contractor runs before instance variables get their default values, could any one explain that to me ?
Example i used in case someone want to try it:
package courseExercise;
class test {
test() {
System.out.println("Super Constructor run");
}
}
public class Init extends test {
private Integer i = 6;
private int j = 8;
Init(int x) {
super();
System.out.println("1-arg const");
}
Init() {
System.out.println("no-arg const");
}
static {
System.out.println("1st static init");
}
public static int d = 10;
{
System.out.println("1st instance init");
}
{
System.out.println("2nd instance init");
}
static {
System.out.println("2nd static init");
}
public static void main(String[] args) {
new Init();
new Init(7);
}
}
Instance variables have default values. For numbers, the default value is 0, for Booleans it is false, and for object references it is null. Values can be assigned during the declaration or within the constructor. Instance variables can be accessed directly by calling the variable name inside the class.
In Java, the order for initialization statements is as follows: static variables and static initializers in order. instance variables and instance initializers in order. constructors.
If you declare a static variable in a class, if you haven't initialized them, just like with instance variables compiler initializes these with default values in the default constructor.
3) The default constructor calls super() and initializes all instance variables to default value like 0, null.
3) The default constructor calls super () and initializes all instance variables to default value like 0, null. 4) If we want to parent class constructor, it must be called in first line of constructor.
Instance variables have default values. For numbers, the default value is 0, for Booleans it is false, and for object references it is null. Values can be assigned during the declaration or within the constructor.
Instance constructors are used to create and initialize any instance member variables when you use the new expression to create an object of a class. To initialize a static class, or static variables in a non-static class, you define a static constructor. For more information, see Static Constructors.
This instance constructor is called whenever an object based on the CoOrds class is created. A constructor like this one, which takes no arguments, is called a default constructor.
The initialization sequence is specified in JLS 12.5:
The relevant part of the spec is:
...
If there is not sufficient space available to allocate memory for the object, then creation of the class instance completes abruptly with an OutOfMemoryError. Otherwise, all the instance variables in the new object, including those declared in superclasses, are initialized to their default values (§4.12.5).
Just before a reference to the newly created object is returned as the result, the indicated constructor is processed to initialize the new object using the following procedure:
...
This is one of the reasons that you should never invoke a non-final
method from a constructor: that method might be overridden by a subclass, in which case the method will be invoked before the subclass has the chance to set state that the method may need. Consider this example:
public class Super {
private final int superValue;
protected Super() {
superValue = getSuperValue();
}
protected int getSuperValue() {
return 1;
}
@Override
public String toString() {
return Integer.toString(superValue);
}
}
public class Sub extends Super {
private final int superValueOverride;
public Sub(int value) {
this.superValueOverride = value;
}
@Override
protected int getSuperValue() {
return superValueOverride;
}
public static void main(String[] args) {
Super s = new Sub(2);
System.out.println(s);
}
}
It looks like s.superValue
should be 2, right? After all, Sub
overrides getSuperValue()
to return the value of superValueOverride
, which is initialized to 2. But that method gets invoked before any of Sub
's fields are initialized (other than to their default values), so s.superValue
is actually 0 (the default value of superValueOverride
).
This is even weirder because superValueOverride
is final
, and yet it seems to change its value! It's 0 when Super
calls getSuperValue()
, and only after the Super
constructor finishes is it assigned its final value of 2 (or whatever is passed in to the constructor).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With