不要从超类构造函数中调用子类方法

请考虑以下代码

/* * 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(); } } 

顺便说一下,你为什么把那些作为静态嵌套类,只是为了造成混乱?