以下示例取自Generics FAQ .
public class Box<T> {
private T t;
public Box(T t) {
this.t = t;
}
public void put(T t) {
this.t = t;
}
public T take() {
return t;
}
public static void main(String[] args) {
Box<?> box = new Box<Object>(new Object());
Object o = new Object();
box.put(o); // Compiler error
o = box.take(); // ok
}
}
如果您查看反编译版本,put() 正在接受一个对象。那么为什么编译器不接受 put() 中的 Object 呢?
public class Box
{
public Box(Object t)
{
this.t = t;
}
public void put(Object t)
{
this.t = t;
}
public Object take()
{
return t;
}
public static void main(String args[])
{
Box box = new Box(new Object());
Object o = new Object();
o = box.take();
}
private Object t;
}
最佳答案
对于编译器的类型检查器,Box<?>
与 Box<Object>
不同。一个Box<Object>
肯定会包含一个对象,所以调用 put(Object)
就可以了。一个Box<?>
有一个未知的类型参数。未知与 Object
不同.
可能是Integer
例如。调用put(Object)
在Box<Integer>
上将是一个错误。如果编译器接受它,那么您可以将程序修改为:
Box<?> box = new Box<Integer>(1);
Object o = new Object();
box.put(o);
并且有非常明显的类型不匹配。允许编译最后一行只会将错误推迟到运行时。
换句话说,泛型类型删除并不意味着编译器在编译时不知道泛型类型。它会尽力在信息被删除之前发现错误。
关于java - 通配符参数化不接受对象 - 为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25943993/