创建未知对象的集合
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 排队,以便它们由送货服务送达。而且,您可能希望对 SMS
和 Email
类型的消息进行排队。
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();
.
我有一个简单的问题:有没有更好的方法来创建一个包含任何类型对象的集合。我是这样的:
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 排队,以便它们由送货服务送达。而且,您可能希望对 SMS
和 Email
类型的消息进行排队。
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();
.