簡體   English   中英

不兼容的通用類型:使用帶有泛型類型的.class時,無法指定子類型

[英]Incompatible Generic Types: Cannot specify sub-type when using .class with generic type

有很多與Java Generics有關的線程,我很難理解為什么Java不支持這個(或者我需要做些什么來使它工作)。

public interface Thinger<T> {

    Class<? extends Thinger<T>> getThingers();
}

public class Thingy<Qwerty> implements Thinger<String> {

    @Override
    public Class<? extends Thinger<String>> getThingers() {
        return Thingx.class;
    }
}

public class Thingx implements Thinger<String> {

    @Override
    public Class<? extends Thinger<String>> getThingers() {
        return Thingy.class;    // Incompatible types error
    }
}

我可以通過兩種方式修復編譯錯誤,但是它們最終都會丟棄我想保留的某種類型的輸入信息!

選項1

Thingy<Qwerty>刪除通用Qwerty

public class Thingy implements Thinger<String> {
    ..
// Ends up fixing the compile error in Thingx

選項2

刪除Class<? extends Thinger<String>>的泛型String Class<? extends Thinger<String>>

public class Thingx implements Thinger<String> {

    @Override
    public Class<? extends Thinger> getThingers() {
        return Thingy.class;    // Fixed!

Thingy.class返回一個Class<Thingy> ,其中Thingy是一個原始類型,因為它沒有為Qwerty指定值。 因為,它是一個原始類型,編譯器只知道Thingy實現Thinger而不是Thinger<String> ,因為該信息因類型擦除而丟失。

要解決此問題,您可以將Class<Thingy>轉換為Class<? extends Thinger> 使用Class#asSubclass Class<? extends Thinger> ,然后編譯器允許隱式轉換為Thinger<String>

return Thingy.class.asSubclass(Thinger.class);

測試時不會產生編譯器或運行時錯誤:

Class<? extends Thinger<String>> c = new Thingx().getThingers();
System.out.println(c.getGenericInterfaces()[0]);

輸出是:

Thinger<java.lang.String>

我無法解決為什么Java不支持這一點

Thingy.class類型為Class<Thingy> ,它不是Class<? extends Thinger<String>>的子類型Class<? extends Thinger<String>> Class<? extends Thinger<String>> ,因為Thingy不是Thinger<String>的子類型。

請注意,由於Thingy是一個泛型類(它使用類型參數聲明),因此使用Thingy本身而不使用類型參數是原始類型 當你使用原始類型時,你禁用所有泛型,所以Thingy (原始類型)的超類型是Thinger (原始類型),而不是Thinger<String> (即使Qwerty沒有參與關系)。 這類似於如果在像Thingy這樣的原始類型上調用方法,所有泛型都在參數和方法的返回類型中關閉,即使它們與Qwerty無關。 這只是避免原始類型的原因之一。

它適用於Thingx.class因為Thingx Thinger<String>的子類型,因為Thingx不是原始類型,因為類Thingx不是通用的。

正如其他人所指出的那樣,似乎沒有任何理由為什么Thingy是通用的,因為類型參數Qwerty從未在Thingy使用Thingy 因此,最好的選擇是刪除它。

暫無
暫無

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

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