当我看到以下错误时,我正在实现某种体系结构:
Error:(33, 55) java: incompatible types: inferred type does not conform to upper bound(s)
inferred: java.io.Serializable
upper bound(s): sandbox.ExpirePolicy,java.io.Serializable
完整的简化代码如下:
interface Configuration<K,V>{}
interface ExpirePolicy{}
interface Factory<T>{}
class FactoryBuilder {
public static <T extends Serializable> Factory<T> of(T instance){
System.out.println(instance.getClass());
return new Factory<T>() {};
}
}
class BaseConfiguration<K,V> implements Configuration<K,V> {
public BaseConfiguration<K,V> setExpiryPolicyFactory(Factory<? extends ExpirePolicy> factory){
return this;
}
}
class C<K,V> extends BaseConfiguration<K,V> {
public C<K,V> setExpiration(){
super.setExpiryPolicyFactory(FactoryBuilder.of((Serializable) getExpirePolicy()));
return this;
}
private ExpirePolicy getExpirePolicy(){
return new ExpirePolicy() {};
}
}
例外情况是尝试使用setExpiryPolicyFactory(Factory<? extends ExpirePolicy> factory)
的实例调用Factory<Serializable>
但是,如果我在extends BaseConfiguration<K,V>
中删除泛型,则程序将成功编译。
因此,类C的下一个声明是正确的:
class C<K,V> extends BaseConfiguration {
public C<K,V> setExpiration(){
super.setExpiryPolicyFactory(FactoryBuilder.of((Serializable) getExpirePolicy()));
return this;
}
private ExpirePolicy getExpirePolicy(){
return new ExpirePolicy() {};
}
}
问题是:为什么第二个实现(类C
)将被成功编译,而第一个实现则没有成功?
UPD:
简单的问题示例(从<T>
中删除extends Base<T>
,程序可以很好地编译:
class Base<T> {
public void test(ArrayList<? extends CharSequence> list) {}
}
class Derived<T> extends Base<T> {
public void callTest() {
super.test(new ArrayList<Integer>());
}
}
答案 0 :(得分:1)
当您从<T>
语句中删除extends Base<T>
时,Base
类开始被视为原始类型。
根据Java spec:
类的超类型可以是原始类型。会员访问 类被视为普通类,并且对超类型的成员访问为 视为原始类型。在类的构造函数中,调用 将super视为对原始类型的方法调用。
这意味着super.test(...)
调用也被视为对原始类型的方法调用,就好像它已被声明为:
public void test(ArrayList list) {}
因此不会发生编译错误。
答案 1 :(得分:0)
工厂创建者似乎应该使用ExpirePolicy
而不是Serializable
来创建工厂。将签名更改为
class FactoryBuilder {
public static <T extends ExpirePolicy> Factory<T> of(T instance){
System.out.println(instance.getClass());
return new Factory<T>() {};
}
}
启用
class C<K,V> extends BaseConfiguration<K,V> {
public C<K,V> setExpiration(){
super.setExpiryPolicyFactory(FactoryBuilder.of(getExpirePolicy()));
return this;
}
private ExpirePolicy getExpirePolicy(){
return new ExpirePolicy() {};
}
}
无需额外强制转换。
C
的第二种实现可以编译,但是带有警告,因为它使用的是原始类型。