我对泛型有点不知所措。我有以下代码:为什么Java编译器不让我返回一个泛型?
public interface SampleValue<T> {
T getValue();
}
public static class SampleBoolean implements SampleValue<Boolean> {
@Override
public Boolean getValue() {
return Boolean.TRUE;
}
}
public static final class SampleValueGenerator {
private SampleValueGenerator() {
// do not call
}
public static <T, R extends SampleValue<T>> R forType(Class<T> clazz) {
if(Boolean.class.equals(clazz)) {
return new SampleBoolean();
}
}
}
当我试试这个,的IntelliJ(即编译)告诉我,R
和SampleBoolean
是不兼容的类型(用于return
线)。
当我尝试的非通用(RAW)返回类型
public static <T> SampleValue forType(Class<T> clazz) {
我没有得到任何错误;
public static <T, R extends SampleValue<?>> R forType(Class<T> clazz) {
(与?
通配符),但是再次失败。而对于
public static <T> SampleValue<T> forType(Class<T> clazz) {
我得到Incompatible types, Found: SampleBoolean, Required: SampleValue<T>
。
我的猜测是它与例如名单不是列表的祖先(但是兄弟姐妹),但我没有看到具有上述树木的木材。
有人可以请解释发生了什么,以及为什么长示例不起作用?
更新:注:当时的想法是有一些更多的if/else对于不同类型的分支,但我停在编译时就开始抱怨起来......
示例代码可以通过声明一个'AnotherEampleSampleBoolean实现SampleValue {...}',然后调用'AnotherSampleBoolean result = forType(Boolean.class)'来挫败。 'R'会被推断为'AnotherSampleBoolean',并且在运行时会抛出'ClassCastException'将'SampleBoolean'转换为'AnotherSampleBoolean'。所以,如果你打算用例如未经检查的铸造过去的编译器错误,声明' SampleValue forType(类)'是最稳定的。 –
Radiodef
@Radiodef使某种意义上说,但' SampleValue forType(类)'失败,太... –
Christian
'公共静态 SampleValue > forType(类 clazz所){'(使用通配符,非通用返回类型)的作品... –
Christian