[英]Error using generic return type (incompatible types: cannot be converted to T)
[英]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
}
}
我可以通過兩種方式修復編譯錯誤,但是它們最終都會丟棄我想保留的某種類型的輸入信息!
在Thingy<Qwerty>
刪除通用Qwerty
。
public class Thingy implements Thinger<String> {
..
// Ends up fixing the compile error in Thingx
刪除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.