创建未知对象的集合

Creating collection of unknown objects

我有一个简单的问题:有没有更好的方法来创建一个包含任何类型对象的集合。我是这样的:

Queue<Object> queue = new LinkedList<Object>();
        queue.add("First Element");
        queue.add(2);
        queue.add(true);

当我阅读有关通用通配符的内容时,我想我可以这样做:

Queue<?> queue = new LinkedList<?>();

但我意识到,这是错误的,所以我问我的程序是否正确,如果可能,我如何使用通配符改进它。

感谢大家的投入。详细说明:我想使用这个队列集合来存储未知数量的未知对象,然后在循环中对每个对象执行一个操作。因此,在这里我有一个两难选择:创建这样一个集合的最佳实践是什么。

这是正确的:-

Queue<Object> queue = new LinkedList<Object>();

这将采用任何 Object 类型作为输入。但是在使用 get() 时,您可以将其转换为实际类型。

以上是类型参数绑定的例子。根据文档:- 有时您可能想要限制可用作参数化类型中的类型参数的类型。例如,对数字进行操作的方法可能只想接受 Number 或其子类的实例。这就是有界类型参数的用途。 提到 Here

关于通配符绑定和类型参数绑定之间的差异的参考 Here:-

What is the difference between a wildcard bound and a type parameter bound?

A wildcard can have only one bound, while a type parameter can have several bounds. A wildcard can have a lower or an upper bound, while there is no such thing as a lower bound for a type parameter.

Wildcard bounds and type parameter bounds are often confused, because they are both called bounds and have in part similar syntax. […]

Syntax:

  type parameter bound     T extends Class & Interface1 & … & InterfaceN

  wildcard bound  
      upper bound          ? extends SuperType
      lower bound          ? super   SubType

A wildcard can have only one bound, either a lower or an upper bound. A list of wildcard bounds is not permitted.

A type parameter, in constrast, can have several bounds, but there is no such thing as a lower bound for a type parameter.

你没有的东西似乎没问题,虽然这可能表明你可能需要单独的 class 而不是收集,你可以在其中将数据存储为字段。

总之你不需要通配符<?>。仅供参考,如

Queue<?> queue = ...

它代表一些你不知道(或暂时不关心)的特定类型。您不想使用它,因为它不允许您 add 收集任何东西,因为您可以尝试将 Cat 放入 Dogs 的集合中。

例如:

List<Dog> dogs = new List<Dog>();
List<?> someList = dogs; // it is OK, thanks to ? someList can be reference to List<Dog>
someList.add(new Cat()); // this would be wrong because Cat is not a Dog, 
                         // and probably shouldn't be placed in container 
                         // where you have lots of Dogs.

通常,如果您觉得需要创建 java.lang.Object 类型的 collection,那么,可能是您的设计存在缺陷。

您可能想要存储特定类型的 objects - 但它们有变体。例如,您可以将 Message objects 排队,以便它们由送货服务送达。而且,您可能希望对 SMSEmail 类型的消息进行排队。

interface Message {
    ...
}

public static class SMS implements Message {
    ...
}

public static class Email implements Message {
    ...
}

在这种情况下,您希望 collection 使用泛型来强制所有元素都是 Message 类型。

您可以通过创建您的 collection 来做到这一点,如下所示

    Queue<? super Message> queue = new LinkedList<Message>();
    queue.add(new SMS());
    queue.add(new Email());

如果你真的想要一个 java.lang.Object 类型的队列,那么,你可以很好地抛弃泛型并使用 type-unsafe collection - Queue queue = new LinkedList();.