创建未知对象的集合

时间:2015-07-04 10:45:15

标签: java generics collections

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

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

当我读到关于gerenic通配符时,我想我可以这样做:

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

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

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

3 个答案:

答案 0 :(得分:1)

这是正确的: -

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

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

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

对于Diff之间的参考一个通配符绑定和一个绑定的类型参数提到{ - 3}}: -

  

通配符绑定和类型参数之间有什么区别   结合吗

     

通配符只能有一个绑定,而类型参数可以有   几个界限。通配符可以具有下限或上限,而   没有类型参数的下限。

     

通配符边界和类型参数边界经常混淆,因为   它们都被称为边界,并且具有部分类似的语法。 [...]

     

语法:

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

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

通配符只能有一个绑定,可以是下限或上限。   不允许使用通配符边界列表。

     

一个类型参数,对比,可以有几个边界,但有   没有类型参数的下限。

答案 1 :(得分:1)

你看起来没什么好看的,虽然它可能表示你可能需要单独的类来代替集合,你可以将数据存储为字段。

无论如何,你不需要通配符<?>。它只能用于参考,如

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.

答案 2 :(得分:0)

通常,如果您认为需要创建<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-configuration SYSTEM "src\dtd\hibernate-configuration-3.0.dtd" > <hibernate-configuration> <session-factory> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <property name="connection.url">jdbc:mysql://localhost:3306/mydb</property> <property name="connection.username">root</property> <property name="connection.password">soumava</property> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <property name="show_sql">true</property> <property name="format_sql">true</property> <mapping resource="User.hbm.xml" /> <mapping resource="Role.hbm.xml" /> </session-factory> </hibernate-configuration> 类型的集合,那么,您的设计可能存在缺陷。

您可能希望存储特定类型的对象 - 但它们具有变体。例如,您可以对java.lang.Object个对象进行排队,以便它们由传递服务传递。而且,您可能希望将MessageSMS类型的消息排队。

Email

在这种情况下,您希望您的收藏集使用泛型来强制所有元素都是interface Message { ... } public static class SMS implements Message { ... } public static class Email implements Message { ... } 类型。

您可以通过创建如下所示的集合来实现这一目标

Message

如果你真的想要一个 Queue<? super Message> queue = new LinkedList<Message>(); queue.add(new SMS()); queue.add(new Email()); 类型的队列,那么,你可以放弃泛型并使用类型不安全的集合 - java.lang.Object