我正在用泛型做一個實驗,我最近遇到了這種現象。在引數化類的建構式中,我正在執行未經檢查的強制轉換。我知道這是不好的做法(我的 IDE 也應該給我一個警告)。在我的main()方法中,我希望第一行能夠成功運行,而第二行會導致 aClassCastException被拋出。但是,這不會發生。
我希望該行Animal<String> bad = new Animal()會引發例外,因為(T) this在Animal建構式中將有效地變為(String) thiswhere thisis of type Animal;這當然是無效的演員表。但是,這不會發生。程式運行成功并退出。
public class Generics {
public static class Animal<T> {
private final T value;
@SuppressWarnings("unchecked")
public Animal() {
this.value = (T) this;
System.out.println(value.getClass());
}
}
public static class Cat extends Animal<Cat> {
public Cat() {
super(); /* of course, this works */
}
}
public static void main(String[] args) {
Cat cat = new Cat(); /* all good */
Animal<String> test = new Animal<>();
}
}
此外,列印 的值會value.getClass()產生意想不到的輸出:
Generics$Cat /* as expected */
Generics$Animal /* expected a ClassCastException here */
我知道這是使用泛型的一種奇怪方式,但正如我之前所說,這只是一個實驗。我只想知道為什么這段代碼運行時沒有拋出例外。如果您需要更多資訊,請在評論中告訴我,我會相應地編輯問題。謝謝!
我也意識到這篇文章與這個問題相似。但是,我不完全確定該問題的作者試圖在那里做什么,因為他的代碼結構與我的不同。
uj5u.com熱心網友回復:
Louis Wasserman 正確地指出,您的“演員”在編譯時T被擦除Object,但您走在正確的軌道上。然而,相反,失敗的轉換將被插入到依賴泛型的代碼中:
public class Animal<T> {
T value;
@SuppressWarnings("unchecked")
public Animal() {
this.value = (T) this;
}
T getValue() {
return value;
}
}
到目前為止,這本身不會導致例外,因為物理欄位型別value是Object. 但是,您將在此處獲得ClassCastException:
void thisFails() {
Animal<String> animal = new Animal();
// ^ animal.value is not a String!
String value = animal.getValue();
// This is implemented by the compiler as
// `String value = (String) animal.getValue()`
// and *this* will fail at runtime with ClassCastException.
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/529769.html
標籤:爪哇仿制药铸件
