Java 具有方法调用转换的类型的多个边界
考虑这个小测试类:Java 具有方法调用转换的类型的多个边界,java,generics,type-erasure,Java,Generics,Type Erasure,考虑这个小测试类: import java.util.List; public abstract class Test { // CAN modify this constructor interface public <T extends Runnable & Comparable<T>> Test(List<T> l) { setList((List<Runnable>)l); // <--
import java.util.List;
public abstract class Test {
// CAN modify this constructor interface
public <T extends Runnable & Comparable<T>> Test(List<T> l) {
setList((List<Runnable>)l); // <-- (a) warning
setList(l); // <-- (b) error
}
// CANNOT modify this interface
public abstract void setList(List<Runnable> l);
}
我在这里的理解是不能将t
转换为Runnable
,因为这可能被认为是一个缩小操作,但这是违反直觉的,因为t
与Runnable
和Comparable
相交
在这种情况下,我必须将T
的实例(a)转换为List
编辑
答案是肯定的,正如Bhesh在下面指出的,泛型类型在Java中是不变的。如果我可以使用以下选项,则不会发生错误(b):
public abstract void setList(List<? extends Runnable> l);
public abstract void setList(Lista)T
is-aRunnable
但是List
is-not-aList
。泛型类型在Java中是不变的
b) 原因同上。方法参数在Java中也是不变的。(注意:方法参数是协变的。)
铸入setList((List)l)代码>应该是安全的,因为我们知道T
总是实现Runnable
。这是注释@SuppressWarnings(“未选中”)
存在的情况类型
还有一个问题可能是(取决于您的情况)您正在从构造函数调用一个可重写的方法
public abstract void setList(List<? extends Runnable> l);