爲什麼在Java中可能會出現以下情況?爲什麼有可能新增一個接口陣列
Integer[] ints = (Integer[])new Comparable[10];
但它在運行時得到ClassCastException
。什麼是new
接口的數組的用例。
爲什麼在Java中可能會出現以下情況?爲什麼有可能新增一個接口陣列
Integer[] ints = (Integer[])new Comparable[10];
但它在運行時得到ClassCastException
。什麼是new
接口的數組的用例。
對於這種情況:你有一個接口和實現接口的兩個(或更多)類:
interface MyInterface
{
public void someMethod();
}
class MyClass1 implements MyInterface
{
public void someMethod() { System.out.println("foo");}
}
class MyClass2 implements MyInterface
{
public void someMethod() { System.out.println("bar");}
}
你這樣稱呼它:
public static void main(String[] args)
{
MyInterface[] array = new MyInterface[2];
array[0] = new MyClass1();
array[1] = new MyClass2();
array[0].someMethod();
array[1].someMethod();
}
接口的數組爲您提供了在陣列中保存該接口的不同實現的方法
請解釋downvote嗎?我弄錯了什麼嗎? – ParkerHalo
要回答具體問題:
Comparable toComplare[] = new Comparable[10];
爲什麼不創建一個數組,允許您存儲任何實現了Comparable接口的對象?
的觀點是:接口表示「常用功能」 - 這可能有助於只看看從「視圖」對象。
當然,該陣列中存儲的對象總是有一些「真實」類 - 但所有這些對象都將實現接口提供的功能。
所以你可以做這樣的事情:
toCompare[0] = new Integer(5);
toCompare[1] = new BigDecimal("3.2");
...
我並不是說這是東西,你會經常使用,但說的 - 它可以讓你「收集」的對象在一定的,具體的「觀察「他們的能力。這也是值得指出的是:具有這樣的陣列做不意味着你將能夠做到:
toCompare[0].compareTo(toCompare[1]);
成功!
除此之外:一個轉換總是暗示你,程序員知道編譯器不知道的東西。所以編譯器退後一步,讓你做到這一點 - 假設你知道你在做什麼。但是,因爲你在問題中顯示的代碼顯然是而不是是正確的,所以在運行時真實回來咬你。是的,可以在編譯時決定給定的代碼是不正確的。
有Integer
實施Comparable
,並不意味着Integer[]
implements Comparable[]
,所以你不能轉換不同類型的數組。但是,您可以將Integer
放入Comparable[]
數組的元素中。
這是錯誤的。你可以絕對地將'Integer []'賦值給'Comparable []'。這編譯和運行得很好:'Comparable [] x = new Integer [10];' – Thilo
這與我寫的完全相反。試試這個'Integer [] ints =(Integer [])new Comparable [] {1};',你將會收到'Exception in thread'main「java.lang.ClassCastException:[Ljava.lang.Comparable;不能轉換爲[Ljava.lang.Integer;' – partlov
你寫了''Integer []'沒有實現'Comparable []'「。這是錯誤的。每個'Integer []'也是一個'Comparable []'。 – Thilo
編譯器查看右側的類型,並看到它是一個數組Comparable
。一般來說,它可能是Integer[]
(因爲它可以指定爲Comparable[]
)。
我們知道它不會是Integer[]
,因爲右邊的表達式是一個構造函數調用。但編譯器看起來並不那麼遠。它使用相同的邏輯,就好像該表達式是一個聲明類型爲Comparable[]
的方法調用。它沒有看清楚實際的類型。
所以編譯器會接受你的類型轉換,因爲它可能可能成功。它只會拒絕根本無法工作的演員(根據聲明的類型),例如鑄造Integer
到String
。
請注意,它可能是一個設計缺陷,允許在數組中的這種協變量。您可以將Integer[]
投射到Comparable[]
,但這有問題,因此您的不能投List<Integer>
到List<Comparable>
。
ClassCastException
是由於堆污染。 這裏尋找更多細節http://www.angelikalanger.com/GenericsFAQ/FAQSections/TechnicalDetails.html#FAQ050new
使用情況的接口陣列/只接口與任何類對象,工具該接口(或)給出匿名內部類定義來填補它。數組無法發生堆污染,因爲它們在運行時檢查組件類型(它不會像使用泛型集合一樣被擦除)。如果您嘗試輸入不好的東西,則會得到ArrayStoreExceptions。 – Thilo
這是因爲要執行縮小引用轉換
類整數實現可比接口:
public final class Integer extends Number implements Comparable<Integer>
見:5.1.6. Narrowing Reference Conversion
從任何數組類型SC []與任何陣列類型TC []相關,前提條件是SC和TC是參考類型,而re是從SC到TC的縮小參考轉換。
此類轉換需要在運行時進行測試,以確定實際參考值是否爲新類型的合法值。如果不是,則引發ClassCastException。
java在運行時識別類型。鑄造不能隱藏真實的類型。 –
'Integer'是一個「Comparable」,但「Comparable」不一定是「Integer」。 – Mena
這不是創建接口的實例,而是創建一個實現接口的類。 –