java - 通配符参数化不接受对象 - 为什么?

标签 java generics

以下示例取自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/

相关文章:

Java 排序映射或数组

c# - C# 扩展方法中的泛型约束

java - 如何创建具有两个泛型的 java 类?

c# - 默认(T)与 Activator.CreateInstance(T)

swift - 协议(protocol)不符合自身?

java - Select :multiple in Spring? 使用什么类型

JavaEE : Login-config, 不同角色的不同形式

Java多线程与方法调用结合使用?

C# 使用泛型类而不指定类型

java - 如何在 Android 中的操作栏下方添加阴影?