【问题标题】:Should I declare/Initialize ArrayLists as Lists, ArrayLists, or ArrayLists of <Cat>我应该将 ArrayLists 声明/初始化为 <Cat> 的 Lists、ArrayLists 还是 ArrayLists
【发布时间】:2011-07-26 04:24:49
【问题描述】:

这样声明一个集合有什么区别

public class CatHerder{
    private List cats;
    public CatHerder(){
        this.cats = new ArrayList<Cat>();
    }
}
//or
public class CatHerder{
    private ArrayList cats;
    public CatHerder(){
        this.cats = new ArrayList();
    }
}
//or
public class CatHerder{
    private ArrayList<Cat> cats;
    public CatHerder(){
        this.cats = new ArrayList<Cat>();
    }
}

【问题讨论】:

    标签: java list collections arraylist


    【解决方案1】:

    您应该将其声明为List&lt;Cat&gt;,并将其初始化为ArrayList&lt;Cat&gt;

    List 是一个接口,ArrayList 是一个实现类。几乎总是针对接口而不是实现进行编码。这样,如果您以后需要更改实现,它不会破坏针对接口编写代码的消费者。

    根据您实际使用列表的方式,您甚至可以使用不太具体的java.util.CollectionList 扩展的接口)。

    至于List&lt;Cat&gt;(您可以将其读作“猫列表”)与List:这是Java 的generics,它确保了编译时类型的安全。简而言之,它让编译器确保List 只包含Cat 对象。


    public class CatHerder{
        private final List<Cat> cats;
        public CatHerder(){
            this.cats = new ArrayList<Cat>();
        }
    }
    

    【讨论】:

    【解决方案2】:

    为了确保类型安全,并且因为当前的 Java 编译器会在泛型类型没有类型参数时报错,所以您应该始终显式指定类型 - 如果您真的不在乎,则应指定 &lt;?&gt;

    也就是说,除非您使用特定于 ArrayList 类的东西,否则您应该使用 List&lt;Cat&gt; 以避免将您的代码绑定到特定的 List 实现。

    【讨论】:

      【解决方案3】:

      我会做以下事情。

      public class CatHerder{
          private final List<Cat> cats = new ArrayList<Cat>();
      }
      

      【讨论】:

      • 6 年后,假设 java 7+ 我更喜欢使用 Listcats = new ArrayList(); 进行初始化。我从 eclipse 声纳插件中选择了这个。引用 Sonar 规则 id 2293,“Java 7 引入了菱形运算符 () 以减少泛型代码的冗长。例如,不必在其声明和构造函数中声明 List 的类型,您现在可以简化构造函数用 声明,编译器会推断类型。”
      【解决方案4】:

      正如 Matt 已经说过的,使用最常见的接口/超类是最好的方法。 确保始终声明出现在列表中的类型,因此将其设为 List&lt;Cat&gt; 甚至 List&lt;? extends Cat&gt;

      如果稍后您想用 LinkedList 替换 ArrayList,则无需更改声明,只需更改实例化即可。

      【讨论】:

        【解决方案5】:

        ListArrayList 更灵活,List&lt;Cat&gt;List 更安全。所以List&lt;Cat&gt;是不错的选择。

        【讨论】:

          【解决方案6】:

          首先,List 是一个接口,ArrayListList 接口的一个实现(实际上,它是AbstractListimplements List 的子类)。因此List cats = new ArrayList() 是有效的,因为ArrayList is-a List

          为此:

          private List cats;
          

          cats 成为原始类型(没有对 List 的通用类型的引用),它没有被参数化。

          您的第三个解决方案是正确的(它解决了选项 1 的问题),

          private ArrayList<Cat> cats;
          

          您已将用于List&lt;E&gt; 的通用类型E 绑定到类型Cat。因此,cats 的实例化是有效的,因为通用边界是相同的。

          您的第二个解决方案只允许实例化 cats 中的 ArrayList。其他 2 个选项允许您实例化任何 is-a List 的对象,例如LinkedList.

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2016-11-03
            • 1970-01-01
            • 2012-12-05
            • 2014-01-24
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-05-17
            相关资源
            最近更新 更多