I'm using Java 7 and got 3 classes:
TestSuper.java
public abstract class TestSuper {
public TestSuper() {
testMethod();
}
protected abstract void testMethod();
}
TestNull.java
public class TestNull extends TestSuper {
private String test = "Test";
public TestNull() {
super();
System.out.println(test);
}
@Override
protected void testMethod() {
System.out.println(test);
}
}
TestMain.java
public class TestMain {
public static void main(String[] args) {
new TestNull();
}
}
Output:
null
Test
Why does this happen and is there a good workaround for it?
2. Use of super with methods. This is used when we want to call the parent class method. So whenever a parent and child class have the same-named methods then to resolve ambiguity we use the super keyword.
Use of super() to access superclass constructor As we know, when an object of a class is created, its default constructor is automatically called. To explicitly call the superclass constructor from the subclass constructor, we use super() .
NULL is a special variable of type Undefined. Unlike a variable that is truly undefined, the value ! NULL can be assigned to other variables and used in comparisons.
Actually, nothing will be displayed. Since the class named Object is the superclass of all classes in Java. If you call "super()" without any superclass, Internally, the default constructor of the Object class will be invoked (which displays nothing).
When you call new TestNull();
you're calling the constructor of the class TestNull
, which it calls the super()
constructor: it contains a call to the method implemented in TestNull
, where you print the String field, at this time the fields of the sub-class TestNull
are not yet initialized, i.e. are null.
After the super constructor call, all the fields will be initialized, and therefore the second print actually show the new value of the (initialized) string.
The key point here is that fields of a sub-class are initialized after the instantiation of the super-classes.
A workaround? It depends on what exact behaviour you desire: maybe it makes sense to NOT call the abstract method in the super constructor (i.e. in the constructor of the TestSuper
class).
According to JLS 8.1.1.1 Abstract Class
A subclass of an abstract class that is not itself abstract may be instantiated, resulting in the execution of a constructor for the abstract class and, Therefore, the execution of the Field Initializers for instance variables of that class.
You are calling an overridable instance method (which also calls an instance field, in your case private String test = "Test";
) in the constructor. This might cause inconsistencies since the instance is not fully constructed. This is a bad practice, so avoid it:
public TestSuper() {
testMethod();
}
Please read this thread: What's wrong with overridable method calls in constructors?
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