簡體   English   中英

Java泛型編譯錯誤涉及Class <?延伸T>

[英]Java generics compile error involving Class<? extends T>

這個程序不編譯:

public class xx {
    static class Class1<C> {
        void method1(C p) {
        }
    }
    static class Class2<T> extends Class1<Class<? extends T>> {
        T object;
        void method2() {
            this.method1(this.object.getClass());
        }
    }
}

錯誤是:

xx.java:10: method1(java.lang.Class<? extends T>) in xx.Class1<java.lang.Class<? extends T>>
cannot be applied to (java.lang.Class<capture#215 of ? extends java.lang.Object>)
        this.method1(this.object.getClass());

為什么會這樣? 為什么編譯器似乎相信object.getClass()返回Class<? extends Object> Class<? extends Object>而不是Class<? extends T> Class<? extends T>

您的代碼中的T上沒有上限設置,所以? extends T ? extends T真的無異於? extends Object ? extends Object 就在昨天,我玩了一個類似的例子,並打了這個障礙。 我有

static <T> T newInstance(T o) throws Exception {
  final Class<? extends T> c = o.getClass();
  return c.newInstance();
}

它抱怨同樣的錯誤。 考慮一下: Object.getClass()的返回類型是Class<?> ,編譯器想要捕獲? 成為具體類型。 但相反,我們不想捕獲? ,但要“捕獲上限” T - 並且在Java的泛型中沒有這樣的東西。

Object.getClass()被定義為返回一個Class<? extends |T|> Class<? extends |T|> ,其中T是靜態已知類型的接收器(調用對象getClass() )。 特別注意垂直條, 擦除操作符 類型變量的擦除是其最左邊界的擦除。 在你的情況下,這是隱式綁定Object 所以你得到一個Class<? extends Object> Class<? extends Object> ,而不是Class<? extends T> Class<? extends T>

這是為什么?

想象一下T = List<Integer> ,如果沒有未經檢查的警告 ,您可以突然執行以下操作:

List<String> myStrings = new ArrayList<>();
List<Integer> myInts = new ArrayList<>();
List<Integer> myIntyStrings = myInts.getClass().cast(myStrings);
myIntyStrings.add(-1);
String myString = myStrings.get(0); // BANG!

但幸運的是,我們確實收到警告..;)

根據getClass()的文檔,返回的對象的類型為Class< ? extends |X| > Class< ? extends |X| > Class< ? extends |X| > ,其中|X| 是調用該方法的實例類型的擦除。

因此,在類型為T的對象上調用getClass()會返回Class< ? extends Object > Class< ? extends Object > 我們在此API中沒有關於T綁定信息。

通常,在泛型類上使用反射的API要求客戶端將類型為Class< T >的附加參數傳遞給相關的構造函數或泛型方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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