簡體   English   中英

java.lang.Class泛型和通配符

[英]java.lang.Class generics and wildcards

為什么以下代碼無法編譯?

interface Iface<T> { }

class Impl<T> implements Iface<T> { }

class TestCase {
    static Class<? extends Iface<?>> clazz = Impl.class;
}

錯誤是

java:不兼容的類型: java.lang.Class<Impl>無法轉換為java.lang.Class<? extends Iface<?>> java.lang.Class<? extends Iface<?>>

但我不明白為什么通配符不能捕獲。

這里的子類型關系是:

          Class<? extends Iface>
           ╱                  ╲
Class<? extends Iface<?>>   Class<Impl>

(我在回答'無法從List<List>轉換為List<List<?>> '時解釋了這一點 。)

所以基本上它不會編譯,因為它是一個橫向轉換。

如果有可能,你可以進行我在那里描述的演員:

(Class<? extends Iface<?>>)(Class<? extends Impl>)Impl.class

如果你不能進行演員表演,那么你可能只需處理一個原始的有界Class<? extends Iface> Class<? extends Iface> 它主要是因為警告而煩人,但卻開啟了出錯的可能性:

interface Iface<T> {
    void accept(T a);
}

class Impl2 implements Iface<String> {
    public void accept(String a) { }
}

class TestCase {
    static Class<? extends Iface> clazz = Impl2.class;

    public static void main(String[] args) throws Exception {
        // throws ClassCastException
        clazz.newInstance().accept(new Object());
    }
}

不太可能發生,但這取決於你在做什么我想。


我傾向於認為這是Java類型系統的問題。

  • 可能應該有一個類型參數的特殊規則? extends T<?> ? extends T<?>包含一個類型參數? extends T ? extends T使得例如一個Class<? extends T> Class<? extends T>轉換為Class<? extends T<?>> Class<? extends T<?>> 從定義子類型的現有方式( TT<?>的超類型)的角度來看,這沒有意義,但從類型安全的角度來看它是有意義的。

  • 或者例如List.class應該是Class<List<?>>而不是Class<List>

  • 或者其他一些比我更聰明的聰明人可以想到。

我上面描述的ClassCastException的有趣之處在於它完全是人為的。 實際上,使用未經檢查的強制轉換防止它會導致警告。

我想,只是表明Java中的泛型尚未完成。

由於類型擦除 ,當你說Impl.class你得到一個Class<Impl> 也就是說,你可以說

Class<Impl> clazz = Impl.class;

泛型是編譯時類型安全功能。

暫無
暫無

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

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