One of my classes inherits from a class in a framework I use. The superclass calls a method in its constructor which I overwrite in my own class. The method uses a field I want to initialize before it is called by the super constructor to avoid a NullPointerException.
Is there any way to do this?
Here is a synthetic test scenario, I want c
in Child
to not be null when call
is called.
public class Test {
public static class Parent {
public Parent() {
super();
call();
}
// only called from parent constructor
public void call() {
System.out.println("Parent");
}
}
public static class Child extends Parent {
private Child c = this;
public Child() {
super();
}
// only called from parent constructor
public void call() {
System.out.println("Child, c is " + (c == null ? "null" : "this"));
}
}
public static void main(String[] args) {
new Child();
}
}
Prior to Java 7, that was possible. I could get by with stunts like this:
public static class Child extends Parent {
private Child c;
private Child(Object unused) {
super();
}
public Child() {
this(c = this);
}
// only called from parent constructor
public void call() {
System.out.println("Child, c is " + (c == null ? "null" : "this"));
}
}
Now, that won't work anymore. I appreciate the additional safety, but the call from super destroys any safety gained by it and reduces the flexibility.
I'd like a way to circumvent this restriction. As an alternative, I'd like to know what's gained by an restriction that spares the super constructor case.
A static initializer will be called before the super class constructor. However, you won't be able to set any non-static fields, so it most likely won't help.
http://docs.oracle.com/javase/tutorial/java/javaOO/initial.html
A non-static initialization block also doesn't help as it is called after the super class constructor completes.
Another approach may be to do nothing when called from the super-constructor and make the call again the child constructor, e.g:
public Child() {
super();
call();
}
public void call() {
if (c==null) {
return;
}
System.out.println("do something with c now");
}
This won't work if more stuff happens in the super constructor that is dependent on this method though.
I have to agree with EJP that this is all a bad idea; it would be much better to find a completely different solution that doesn't involve torturing 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