2010-02-10 38 views
18

何時可以將某個對象轉換爲另一個對象?鑄造對象是否必須是另一個對象的子類型?我試圖找出規則...鑄造的Java規則

編輯:我意識到我根本沒有解釋我的問題:基本上,我將對象轉換爲接口類型。但是,在運行時,我得到一個java.lang.ClassCastException。我的對象需要發生什麼,以便我可以將其轉換爲此界面?它是否必須執行它?

感謝

+0

在什麼情況下你真的需要明確對象轉換接口類型? – harto 2010-02-10 02:20:22

+0

你在這裏有一個非常有用的答案。我希望你選擇它。 – orbfish 2011-11-22 18:37:32

回答

1

你可以施放某個對象的運行時類型是你想將它轉換成什麼亞型。

編輯:

是的,你想投就需要實現該接口,以便您成功投放它的對象。

+0

你在想這完全是錯誤的。你應該問的是「在什麼情況下把'Foo'當作'IBar'來處理? – 2010-02-10 02:01:00

+0

如果我想要轉換爲該接口的對象擴展了實現接口的類,該怎麼辦?將避免運行時錯誤? – alan 2010-02-10 02:01:38

+0

噢好..我嘗試重寫我原來的評論,因爲它沒有真正有意義的第一次嘗試 – alan 2010-02-10 02:02:10

27

在Java中,有兩種類型的引用變量鑄造:

  • 溯造型:如果你有一個參考 變量是指亞型 對象,你可以把它分配給一個 參考變量的亞型。 你必須做一個明確的演員才能做 這個,結果就是你可以用 這個新的參考變量訪問子類型的成員 。

  • 上溯造型:您可以參考 變量賦值給一個超基準 變量顯式或隱式。 這是一項固有安全的操作 ,因爲該分配限制了新變量 的訪問權限 。

,則需要實現接口直接或間接使接口類型分配類對象的引用。

+0

我不確定你是否寫這個,複製它,或總結,但它很好,讓我意識到我想要的是什麼那樣做沒有意義。 – orbfish 2011-11-22 18:38:25

+0

例子會很有用 – 2013-03-15 21:21:49

+0

由於人工編寫的文本而得到讚揚,而不是一些'B擴展A'的喋喋不休。 – 2015-03-26 19:12:52

1

如果:

interface MyInterface{} 

class MyClass implements MyInterface{} 

然後

MyClass m = new MyClass(); 
MyInterface i = (MyInterface)m; 

是可能的。

2

有一種直觀的方式來思考這個問題 - 你不是用一個轉換來改變一個對象,而只是在已知類型的情況下做一些事情 - 換句話說,你只能轉換成一種類型你的對象已經是。因此,只需查看「對象」鏈,查看適用於您的對象的類型。

因此,如果將鏈接定義在鏈中較高位置的某處(例如,如果您的類的父類實現了它等等),則您只能將其轉換爲接口僅限於。它必須是明確的 - 從你的問題,它聽起來像你可能會認爲,如果你實現方法「void foo()」,那麼你應該能夠轉換到一個接口,定義方法「void foo()」 - 這是有時被描述爲"duck typing"(如果它像鴨子一樣呱呱叫,它是鴨子),但不是java如何工作。

3

這將工作:

class Foo implements Runnable { 
    public void run() {} 
} 

Foo foo = new Foo(); 
System.out.println((Runnable) foo); 

但這不會:

class Bar { 
    public void run() {} 
} 

Bar bar = new Bar(); 
System.out.println((Runnable) bar); 

因爲雖然Barrun()方法可以實施Runnable.run()Bar沒有宣佈實行Runnable所以不能投射到Runnable

Java要求您聲明的實現接口名稱。它沒有duck typing,不像其他一些語言,如PythonGo

2

假設我們要投d對象A,

A中的=(C)d;

因此,編譯器和JVM檢查了內部3個規則。 編譯器在編譯時檢查前2條規則,JVM將在運行時檢查最後一條規則。

第1條(編譯時檢查):

的「d」和C必須有一定的關係(孩子的父母或父母 兒童或同時)類型。如果沒有關係,那麼我們將得到一個 編譯錯誤(不可轉換的類型)。

規則2(編譯時間檢查):

'C' 必須是相同類型或 'A' 的派生類型(子類) 否則,我們將得到一個編譯錯誤(不相容類型)。

規則3(運行時異常):

'd' 必須是相同的或派生的類型的 'C' 否則我們將得到運行時異常(ClassCastException異常 的

運行時對象類型例外)。

查找下面的例子讓更多的想法,

String s = new String("hello"); StringBuffer sb = (StringBuffer)s; // Compile error : Invertible types because there is no relationship between. 

Object o = new String("hello"); StringBuffer sb = (String)o;  // Compile error : Incompatible types because String is not child class of StringBuffer. 

Object o = new String("hello"); StringBuffer sb = (StringBuffer)o; // Runtime Exception : ClassCastException because 'o' is string type and trying to cast into StingBuffer and there is no relationship between String and StringBuffer.