繁体   English   中英

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

[英]Using an Object as argument on unbounded wildcard reference object

简单类:

class Box<T> {
    private T t;

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

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

试图执行put()方法传递Object的实例

Box<?> box = new Box<String>("abc");
box.put(new Object());

编译器指出一个错误:

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

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

谢谢

您的示例清楚地说明了原因。

框的实际类型为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

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

本教程指出:

Collection<?> c = new ArrayList<String>();
c.add(new Object()); // Same compile time error as yours

“由于我们不知道c的元素类型代表什么,因此我们无法向其添加对象。add()方法采用类型E(即集合的元素类型)的参数。当实际类型参数为?时,它将代表某种未知类型。传递给我们的任何参数都必须是该未知类型的子类型。由于我们不知道是什么类型,因此无法传递任何内容。唯一的例外是null,它是一个成员每种类型。

另一方面,给定一个List,我们可以调用get()并利用结果。 结果类型是未知类型,但我们始终知道它是一个对象。 因此,可以安全地将get()的结果分配给Object类型的变量,或将其作为参数传递给需要Object类型的位置。”

解释一下,基本上可以调用get()返回类型,但是不能添加,因为编译器不知道它是什么类型,并且传递的参数需要扩展未知类型。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM