支持Java中的协变类型转换

Tho*_*ung 3 java generics types

Java类型系统仅支持不变类型.所以a List<String>不是List<Object>.A List<String>不是a,List<Object>因为将Integera 插入到a中无效List<String>.但是,存在这种协变类型转换有效的类型.

鉴于A,B和生产者类别:

class A{}
class B{}
interface Producer<T> {
    T next();
}
Run Code Online (Sandbox Code Playgroud)

可以定义协变类型Producer的强制转换:

class Types{
    @SuppressWarnings("unchecked")
    public static <T> Producer<T> cast(Producer<? extends T> producer){
        return (Producer<T>) producer;
    }
}
Run Code Online (Sandbox Code Playgroud)

此方法支持从投Producer<A>Producer<Object>和防止无效石膏样Producer<A>Producer<B>:

Producer<Object> valid = Types.<Object> cast(new Producer<A>());
Producer<A> invalid = Types.<A> cast(new Producer<B>()); //does not compile
Run Code Online (Sandbox Code Playgroud)

我的问题是我无法从执行投Producer<Producer<A>>Producer<Producer<Object>>.

Producer<Producer<A>> producerOfA = new Producer<Producer<A>>();
Producer<Producer<Object>> producerOfObjects = 
   Types.<Producer<Object>> cast(producerOfA); //does not compile
Run Code Online (Sandbox Code Playgroud)

有没有办法说服Java类型系统在用户代码中没有警告的情况下执行这种有效的类型转换?

Lau*_*ves 8

您还没有发布Producer的代码,但是根据名称和断言它应该是协变的,也许你现在说的任何地方:

Producer<Foo>
Run Code Online (Sandbox Code Playgroud)

你应该说:

Producer<? extends Foo>
Run Code Online (Sandbox Code Playgroud)

这将是很好,如果Java的可以自动认识到一个通用的接口相当于其通配符形式(IteratorIterable也是安全的协变,例如),但至少在目前,它没有.