2013-12-20 60 views
1

兩類:上溯造型給人ClassCastException異常

public class ClassA implements ClassC { 
    private static final long serialVersionUID = 1111111111111111111L; 
    public String varA; 
} 

public class ClassB extends ClassA implements ClassC { 
    private static final long serialVersionUID = 4604935970051141456L; 
    public String varB; 
} 

在我的代碼,我有這樣的聲明: ClassB classB;

和方法

myMethod的()

返回一個ClassA目的。

如果我寫:

classB = (ClassB) myMethod(); 

我認爲我將有:

classB.varA = <a value from myMethod()> 
classB.varB = null 

,但事實並非如此:我收到ClassCastException異常

爲什麼?那麼如何快速分配myMethod()ClassB

+0

顯示所有相關代碼。我不確定我瞭解你想要做什麼。 –

+0

一個強制轉換不會改變一個對象的類,它只是驗證該對象是那個類(或該類的某個子類)。如果你的myMethod返回了一個ClassB對象,但是把它輸入爲ClassA,那麼這個轉換就可以工作。 –

+0

我不明白爲什麼B類實現C類,如果A類實現C類,B類擴展A類,那麼B類也不隱式實現C類接口? – Lucas

回答

1

的問題是,你想垂頭喪氣一個ClassAClassB,這是不允許的,因爲實際的對象可能是ClassX(的ClassA另一個子類)不具有明確的轉換。

請看下面的例子,這將拋出ClassCastException(但編譯就好):

public class Main { 
    public static void main(String[] args) { 
     SubB var = (SubB) someMethod();   
    } 

    private static Super someMethod(){ 
     return new SubA(); 
    } 
} 

class Super { } 
class SubA extends Super { } 
class SubB extends Super { } 

代碼編譯完美:

  • someMethod()返回類Super類型。
  • SubA延伸Super所以這種方法定義不違反
  • SubB擴展Super所以它可以投Super類型的對象,以SubB

然而,當你執行這個,你試着投了SubA類型的對象到SubB,這是不可能的。

圖片的標題說明:

  • 不要使用ClassC在此名稱與類名的interface
  • 認沽層次的小例子(超級< - >子),而不是(A < - >乙< - > C)
0

ClassA不是ClassB可互換的。將您的方法更改爲返回ClassC(界面),並將該參考存儲爲ClassC,然後您可以使用ClassAClassB。 A是一個C和B是一個C,但是A不是一個B,儘管B是一個A.如果這有幫助。

+0

請注意,您可以將ClassB對象存儲在類型爲ClassA的引用中,並將其視爲ClassA。如果您想將其視爲ClassB,則可以使用(ClassB)獲取類型爲ClassB的引用。 –

+0

'B'擴展'A',所以'ClassB'就是'ClassA'。我已經把我認爲是問題的答案放在了答案中。 –

1

在Java中強制轉換不像dynamic_cast < ...> C++中的指針。對於後者,如果類型不兼容,則結果爲空指針。在Java中,投射不兼容的引用導致ClassCastException

通常的Java習慣用法是使用instanceof事先測試參考,然後只在結果爲真時執行強制轉換。例如,

ClassA a = myMethod(); 
if (a instanceof ClassB) { 
    ClassB b = (ClassB) a; 
    ... 
}