2010-06-18 89 views
3

考虑下面的代码不要从父类的构造

/* 
* 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/

除了做最后的和笔者建议的方式,有更多的方式来防止上述问题(不要调用从父类的构造方法子类)的发生呢?

+0

究竟是什么问题? – 2010-06-18 16:50:47

+2

em,这是什么问题? – Bozho 2010-06-18 16:50:47

+1

所有这些行为看起来都非常正确。是的,有一个空指针异常,但只是因为你有一个返回null的方法。这很合理。你想要什么样的行为?如果B尚未定义一个变量,您是否想回退A变量? B可以自己做到这一点。 – VoteyDisciple 2010-06-18 16:51:05

回答

2

制作getVar方法最终

这绝对是你需要做什么。

如果您在继承方法的功能以初始化对象,则不应让子类打破该方法。

回答您的问题,其他防止它的方法是使getVar私人在A

见你的代码的这种简化版本:

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

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

+0

>>静态嵌套类对不起。他们不应该是静态的。我只是想通过静态main进行一些快速调用。 – 2010-06-18 17:04:45

相关问题