Рассмотрим следующий код
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package example0;
/**
*
* @author yccheok
*/
public class Main {
static class A {
private final String var;
public A() {
var = getVar();
// Null Pointer Exception.
System.out.println("var string length is " + var.length());
}
public String getVar() {
return "String from A";
}
}
static class B extends A {
private final String bString;
// Before B ever constructed, A constructor will be called.
// A is invoking a overriden getVar, which is trying to return
// an initialized bString.
public B() {
bString = "String from B";
}
@Override
public String getVar() {
return bString;
}
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
B b = new B();
}
}
В настоящее время, на мой взгляд, есть два способа избежать такой проблемы.
Либо делаю урок А финальный класс.
static final class A {
private final String var;
public A() {
var = getVar();
// Null Pointer Exception.
System.out.println("var string length is " + var.length());
}
public String getVar() {
return "String from A";
}
}
Или
Завершение метода getVar
static class A {
private final String var;
public A() {
var = getVar();
// Null Pointer Exception.
System.out.println("var string length is " + var.length());
}
public final String getVar() {
return "String from A";
}
}
Автор пытается предложить способы предотвращения вышеуказанной проблемы. Однако решение кажется обременительным, поскольку есть некоторые правила, которым нужно следовать.
http://benpryor.com/blog/2008/01/02/dont-call-subclass-methods-from-a-superclass-constructor/
Помимо окончательного выполнения и предложенного автором способа, есть ли еще способы предотвратить возникновение вышеуказанной проблемы (не вызывать методы подкласса из конструктора суперкласса)?