java - 不兼容的类型 : inferred type does not conform to upper bound(s)

标签 java generics java-8 typechecking

当我看到以下错误时,我正在实现一些架构:

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() {};
    }
}

异常(exception)是尝试调用 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 )会成功编译而第一个则不能?

更新:

更简单的问题示例(从 <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>());
    }
}

最佳答案

当您删除<T>时来自extends Base<T>声明,Base类开始被视为原始类型

根据Java spec :

The supertype of a class may be a raw type. Member accesses for the class are treated as normal, and member accesses for the supertype are treated as for raw types. In the constructor of the class, calls to super are treated as method calls on a raw type.

这意味着 super.test(...)调用也被视为对原始类型的方法调用,就好像它已被声明为:

public void test(ArrayList list) {}

因此不会发生编译错误。

关于java - 不兼容的类型 : inferred type does not conform to upper bound(s),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51730146/

相关文章:

java - 在类中定义的方法在泛型类 (Java) 中找不到

multithreading - CopyOnWriteArrayList不能按预期工作

java - 使用 lambda 将 List<List<String>> 折叠到 List<String> 中?

java - 在计时器中使用 "if"语句执行任务而不满足指定条件?

c# - 实现多个通用接口(interface) - 类型错误

ios - Parse Xamarin SDK 会显着增加 iOS 应用程序的应用程序大小

java - Liquibase Hibernate Java 8 支持

java - JPA Left Join IS NULL 条件不起作用

java - derby + hibernate ConstraintViolationException 使用多对多关系

java - 在处理程序上调用时, TextView 为空