假設下面的語句的工作:
Collection<SomeType> collection;
Collection<OtherType> otherCollection = (Collection<OtherType>) collection; //illegal
這將打破類型安全泛型是應該提供的。想象一下,您可以將Collection<SomeType>
指定給Collection<OtherType>
。然後將下面的代碼將讓你把東西,是不是SomeType
爲Collection<SomeType>
:
otherCollection.add(new OtherType());
因爲otherCollection
是Collection<OtherType>
,加入new OtherType()
它似乎完全合法的。但otherCollection
實際上是指類型SomeType
的集合。
,這是允許的:
Collection<SomeType> collection;
Collection<OtherType> otherCollection = (Collection<OtherType>) (Collection<?>) collection;
這是type erasure
的含義。由於仿製藥在Java編譯器實現幾乎完全的,而不是在運行時,有關通用類型的幾乎所有類型的信息已經通過erased
生成字節碼的時間。因此,在運行時,Collection<SomeType>
和Collection<OtherType>
是同一類和兩者都是Collection<?>
亞型。通過這種轉換,編譯器只會發出未經檢查的警告,因爲它不知道演員是否安全。
但鑄造,像你在第二個例子中的一個,應避免以避免ClassCastException
在運行時。考慮下面的一系列語句:
Collection<SomeType> collection;
Collection<OtherType> otherCollection = (Collection<OtherType>) (Collection<?>) collection;
collection.add(new SomeType());
otherCollection.add(new OtherType());
現在第4語句之後,就沒有辦法對原收集來告訴它包含哪些對象的具體類型;這可能導致ClassCastException
在運行時訪問集合中的元素。
我看不到這種方法中好的做法,會發生什麼,如果OTHERTYPE,在未來,從SOMETYPE相差這麼多呢?應用程序將停止工作。 – RamonBoza
發生的事情與將SomeType轉換爲OtherType完全相同。你知道,在Java中允許投射。 –
但是,這並不意味着,鑄造是一個很好的做法,如果同一層次的元素 – RamonBoza