何時可以將某個對象轉換爲另一個對象?鑄造對象是否必須是另一個對象的子類型?我試圖找出規則...鑄造的Java規則
編輯:我意識到我根本沒有解釋我的問題:基本上,我將對象轉換爲接口類型。但是,在運行時,我得到一個java.lang.ClassCastException
。我的對象需要發生什麼,以便我可以將其轉換爲此界面?它是否必須執行它?
感謝
何時可以將某個對象轉換爲另一個對象?鑄造對象是否必須是另一個對象的子類型?我試圖找出規則...鑄造的Java規則
編輯:我意識到我根本沒有解釋我的問題:基本上,我將對象轉換爲接口類型。但是,在運行時,我得到一個java.lang.ClassCastException
。我的對象需要發生什麼,以便我可以將其轉換爲此界面?它是否必須執行它?
感謝
在Java中,有兩種類型的引用變量鑄造:
溯造型:如果你有一個參考 變量是指亞型 對象,你可以把它分配給一個 參考變量的亞型。 你必須做一個明確的演員才能做 這個,結果就是你可以用 這個新的參考變量訪問子類型的成員 。
上溯造型:您可以參考 變量賦值給一個超基準 變量顯式或隱式。 這是一項固有安全的操作 ,因爲該分配限制了新變量 的訪問權限 。
是,則需要實現接口直接或間接使接口類型分配類對象的引用。
我不確定你是否寫這個,複製它,或總結,但它很好,讓我意識到我想要的是什麼那樣做沒有意義。 – orbfish 2011-11-22 18:38:25
例子會很有用 – 2013-03-15 21:21:49
由於人工編寫的文本而得到讚揚,而不是一些'B擴展A'的喋喋不休。 – 2015-03-26 19:12:52
如果:
interface MyInterface{}
class MyClass implements MyInterface{}
然後
MyClass m = new MyClass();
MyInterface i = (MyInterface)m;
是可能的。
有一種直觀的方式來思考這個問題 - 你不是用一個轉換來改變一個對象,而只是在已知類型的情況下做一些事情 - 換句話說,你只能轉換成一種類型你的對象已經是。因此,只需查看「對象」鏈,查看適用於您的對象的類型。
因此,如果將鏈接定義在鏈中較高位置的某處(例如,如果您的類的父類實現了它等等),則您只能將其轉換爲接口僅限於。它必須是明確的 - 從你的問題,它聽起來像你可能會認爲,如果你實現方法「void foo()」,那麼你應該能夠轉換到一個接口,定義方法「void foo()」 - 這是有時被描述爲"duck typing"(如果它像鴨子一樣呱呱叫,它是鴨子),但不是java如何工作。
這將工作:
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);
因爲雖然Bar
有run()
方法可以實施Runnable.run()
,Bar
沒有宣佈實行Runnable
所以不能投射到Runnable
。
Java要求您聲明的實現接口名稱。它沒有duck typing,不像其他一些語言,如Python和Go
假設我們要投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.
在什麼情況下你真的需要明確對象轉換接口類型? – harto 2010-02-10 02:20:22
你在這裏有一個非常有用的答案。我希望你選擇它。 – orbfish 2011-11-22 18:37:32