简体   繁体   English

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

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

Simple class: 简单类:

class Box<T> {
    private T t;

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

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

trying to execute put() method passing an instance of Object 试图执行put()方法传递Object的实例

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

Compiler points out an error: 编译器指出一个错误:

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

Compiler in fact does not know what type to expect, but one thing is sure - it will be an Object or a subclass of it. 实际上,编译器不知道期望的类型,但是可以肯定的是-它将是Object或它的子类。 Why is the error raised then? 为什么会引发错误?

thank you 谢谢

Your example clearly explains why. 您的示例清楚地说明了原因。

The actual type of the box is Box<String> . 框的实际类型为Box<String> So you really don't want to be able to put something other than String instances to this box. 因此,您真的不希望将String实例以外的其他内容放置到此框中。

Box<?> means: "a box of some type that is unknown to the compiler". Box<?>意思是:“一个编译器不知道的某种类型的盒子”。 So you can get anything you want from such a box, and you'll get Object instances, but you may not store anything into the box, because the compiler can't guarantee that the object you're storing has the appropriate type: 因此,您可以从这样的盒子中获得所需的任何东西,并且可以获得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

The goal of generics is to make your code type-safe. 泛型的目标是使代码类型安全。 If you could add arbitrary objects to a box that is actually a Box<String> , you wouldn't have any type-safety anymore. 如果您可以向实际上是Box<String>的盒子中添加任意对象,那么您将不再具有任何类型安全性。

This tutorial states that: 本教程指出:

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

"Since we don't know what the element type of c stands for, we cannot add objects to it. The add() method takes arguments of type E, the element type of the collection. When the actual type parameter is ?, it stands for some unknown type. Any parameter we pass to add would have to be a subtype of this unknown type. Since we don't know what type that is, we cannot pass anything in. The sole exception is null, which is a member of every type. “由于我们不知道c的元素类型代表什么,因此我们无法向其添加对象。add()方法采用类型E(即集合的元素类型)的参数。当实际类型参数为?时,它将代表某种未知类型。传递给我们的任何参数都必须是该未知类型的子类型。由于我们不知道是什么类型,因此无法传递任何内容。唯一的例外是null,它是一个成员每种类型。

On the other hand, given a List, we can call get() and make use of the result. 另一方面,给定一个List,我们可以调用get()并利用结果。 The result type is an unknown type, but we always know that it is an object. 结果类型是未知类型,但我们始终知道它是一个对象。 It is therefore safe to assign the result of get() to a variable of type Object or pass it as a parameter where the type Object is expected." 因此,可以安全地将get()的结果分配给Object类型的变量,或将其作为参数传递给需要Object类型的位置。”

To explain, basically you can call get() to return the type, but you cannot add because the compiler doesn't know what type it is and the passed parameter needs to extend the unknown type. 解释一下,基本上可以调用get()返回类型,但是不能添加,因为编译器不知道它是什么类型,并且传递的参数需要扩展未知类型。

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

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