不要从超类构造函数中调用子类方法
请考虑以下代码
/* * 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(); } }
目前,在我看来,有两种方法可以避免这种问题。
要么是A级的最后一堂课。
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/
除了最后和作者建议的方式之外,还有更多方法可以防止上述问题(不要从超类构造函数中调用子类方法)吗?
使getVar方法最终
这绝对是你需要做的。
如果您正在转发初始化对象的方法的function,则不应让子类破坏该方法。
回答你的问题, 另一种防止它的方法是让A
getVar
私有。
查看代码的简化版本:
// A.java class A { private final String var; public A(){ var = getVar(); var.length(); } private String getVar(){ return "This is the value"; } } class B extends A { private final String other; public B(){ other = "Other string"; } public String getVar(){ return other; } } class Main{ public static void main( String [] args ) { new B(); } }
顺便说一下,你为什么把那些作为静态嵌套类,只是为了造成混乱?