2010-06-18 49 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