2013-02-07 53 views
3

我有靜態域F類A:BT和繼承在Java中

class A { 
    public static String F = null; 
} 

類別:

class B extends A { 
    public static String F = "somestring"; 
} 

並用的方法的類型化的類使用場F:

class C<T extends A> { 
    public void someMethod() { 
     String someString = T.F; 
     // Manipulations with someString 
    } 
} 

然後我的代碼調用它。

C<B> c = new C<B>(); 
c.someMethod(); 

我試圖用someString操作時出現空指針異常。所以,T.F是null,但T是B,所以它應該是「somestring」!爲什麼?

回答

7

您不能覆蓋字段。既然是延伸的,它總是會使用領域A.

在一個與一個在加入A類和B返回F.從那裏一個getter,重寫方法B.

class A { 
    public String getF(){ 
     return null; 
    } 
} 

class B { 
    @Override 
    public String getF(){ 
     return "someString"; 
    } 
} 
2

這與泛型沒有關係。

一個類的字段不能被子類覆蓋 - 只有方法可以。所以,即使你在你的子類中定義了一個與超類中的字段相同的字段,你也只是創建了一個新字段,它只是恰好有相同的名字,但實際上是陰影(而不是覆蓋)前一個字段。

考慮在您的子類的構造函數中使用字段的默認值進行賦值。那麼它應該工作。

2

Java中的靜態成員可以隱藏,但不能被覆蓋。在編譯時解析靜態成員的引用 - 在編譯時,唯一已知類型的T是A.

請參閱http://www.coderanch.com/how-to/java/OverridingVsHiding

編輯:無論如何,字段不能被覆蓋,無論它是靜態的還是實例。

1
  1. 這是因爲所有的Astatic成員共同獨自A,不能由B繼承。

  2. 沒有新的static成員,它不存在於A中,可以存在於B中。

  3. 實際上,當你說

    class C < T extends A > { ... }

您只能使用方法(包括靜態和實例 - 除非@Override n)和它是常見的A領域。因此,由於F不是實例字段,因此它不會被覆蓋,並且JVM會在A中發現F

因此,您將得到一個NPE。