使用对象作为无界通配符引用对象的参数

Łuk*_*asz 3 java generics unbounded-wildcard

简单类:

class Box<T> {
    private T t;

    public Box(T t) {
        this.t = t;
    }

    public void put(T t) {
        this.t = t;
    }
}
Run Code Online (Sandbox Code Playgroud)

尝试执行传递对象实例的 put() 方法

Box<?> box = new Box<String>("abc");
box.put(new Object());
Run Code Online (Sandbox Code Playgroud)

编译器指出错误:

The method put(capture#1-of ?) in the type Box<capture#1-of ?> is not applicable for the arguments (Object)
Run Code Online (Sandbox Code Playgroud)

编译器实际上不知道期望什么类型,但有一件事是肯定的 - 它会是一个 Object 或它的子类。为什么会引发错误?

谢谢你

JB *_*zet 5

你的例子清楚地解释了原因。

盒子的实际类型是Box<String>. 所以你真的不希望能够把 String 实例以外的东西放到这个盒子里。

Box<?>意思是:“编译器未知的某种类型的盒子”。所以你可以从这样的盒子中得到任何你想要的东西,你会得到 Object 实例,但你可能不会在盒子里存储任何东西,因为编译器不能保证你存储的对象具有适当的类型:

class Box<T> {
    private T t;

    public Box(T t) {
        this.t = t;
    }

    public void put(T t) {
        this.t = t;
    }

    public T get() {
        return t;
    }
}

Box<?> box = new Box<String>("abc");
Object o = box.get(); // no problem
box.put(new Object()); // fail
Run Code Online (Sandbox Code Playgroud)

泛型的目标是使您的代码类型安全。如果您可以将任意对象添加到实际上是 a 的框Box<String>,那么您将不再具有任何类型安全性。