有很多与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
}
}
我可以通过两种方式解决编译错误,但是它们最终都会丢弃我想保留的某种类型的输入信息!
将通用Qwerty
放入Thingy<Qwerty>
。
public class Thingy implements Thinger<String> {
..
// Ends up fixing the compile error in Thingx
删除String
Class<? extends Thinger<String>>
public class Thingx implements Thinger<String> {
@Override
public Class<? extends Thinger> getThingers() {
return Thingy.class; // Fixed!
答案 0 :(得分:0)
Thingy.class
返回Class<Thingy>
,其中Thingy
是原始类型,因为它没有为Qwerty
指定值。由于它是原始类型,因此编译器只知道Thingy
实现Thinger
而不是Thinger<String>
,因为该信息因类型擦除而丢失。
要解决此问题,您可以使用Class#asSubclass
将Class<Thingy>
转换为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>
答案 1 :(得分:0)
我无法理清为什么Java不支持这个
Thingy.class
的{{1}}类型不是Class<Thingy>
的子类型,因为Class<? extends Thinger<String>>
不是Thingy
的子类型。
请注意,由于Thinger<String>
是泛型类(使用类型参数声明),因此在没有类型参数的情况下单独使用Thingy
是原始类型。当您使用原始类型时,禁用所有泛型,因此Thingy
(原始类型)的超类型为Thingy
(原始类型),而不是Thinger
(即使{{1}不参与关系)。这类似于如果在Thinger<String>
之类的原始类型上调用方法,所有泛型都在参数中关闭并返回方法的类型,即使它们与Qwerty
无关。这只是避免原始类型的原因之一。
适用于Thingy
,因为Qwerty
是Thingx.class
的子类型,因为Thingx
不是原始类型,因为类{{ 1}}不是通用的。
正如其他人所指出的那样,Thinger<String>
通用似乎没有任何理由,因为类型参数Thingx
从未在Thingx
中使用。所以最好的选择就是删除它。