簡體   English   中英

當類變成泛型時,為什么“不兼容類型”的編譯錯誤變成警告?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM