[英]Why does an “Incompatible types” compile error turn into a warning when a class is made generic?
我有此代碼,無法編譯:
import java.util.ArrayList;
import java.util.List;
public class TypeSafetyTest {
public static void main(String[] args) {
TypeSafetyTest test = new TypeSafetyTest();
test.run();
}
private void run() {
Car car = new Car();
List<String> wheelWeights = car.getWheelWeights();
}
private class Car {
List<Double> wheelWeights = new ArrayList<Double>();
public List<Double> getWheelWeights() {
return wheelWeights;
}
public void setWheelWeights(List<Double> wheelWeights) {
this.wheelWeights = wheelWeights;
}
}
}
它在行上給出“不兼容的類型”錯誤:
List<String> wheelWeights = car.getWheelWeights();
但是,如果我更改行:
private class Car {
至
private class Car<T> {
然后代碼會成功編譯,並在以前出現編譯錯誤的行上顯示警告“未檢查的分配”。 為什么會這樣呢? 我期望這兩種情況下都會產生編譯錯誤。
我看到的一個問題是:
public List<Double> getWheelWeights() {
return wheelWeights;
}
返回Double
類型List
,但是您將其分配給List<String>
更改Car<T>
時未看到編譯錯誤的原因是,因為您的實例創建是原始類型,這會告訴編譯器由於向后兼容性而忽略了編譯時的類型安全性。
Car<Object> car = new Car<Object>();
如果您這樣更改對象,則將看到編譯器再次拋出該消息。
有關更多信息,請參考JLS 4.8 。
這是來自JLS的示例:
class Outer<T>{
class Inner<S> {
S s;
}
}
Outer.Inner<Double> x = null; // illegal
不可能以部分原始類型(“稀有”類型)訪問Inner,因為Outer本身是原始的,因此所有內部類(包括Inner)也是原始的,因此無法將任何類型參數傳遞給Inner
僅允許使用原始類型作為對遺留代碼兼容性的讓步。 強烈建議不要在將泛型引入Java編程語言后在編寫的代碼中使用原始類型。 Java編程語言的未來版本可能會禁止使用原始類型。
我建議閱讀泛型(已更新)
將Car
更改為Car<T>
, Car
成為通用類。 因此,您的car
對象現在具有原始類型Car
,因為您沒有提供任何類型參數。 原始類型的非靜態非繼承成員也是原始類型。 這意味着getWheelWeights()
現在返回原始類型。 而且由於它是原始類型,所以它執行未經檢查的轉換,這意味着您只會收到警告,而不是錯誤。
您可以通過為car
提供類型參數來解決此問題。 例如
Car<Object> car = new Car();
請注意,如果您希望使用泛型的類型安全性,則根本不應該使用原始類型。 它們只是針對通用代碼的兼容性修補程序,因此具有傳染性,並且無需檢查原始類型。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.