【问题标题】:What does "List<Integer> list = new ArrayList<Integer>(); " actually mean?“List<Integer> list = new ArrayList<Integer>();”实际上是什么意思?
【发布时间】:2017-09-13 17:11:08
【问题描述】:

我对 Java 很陌生,我想知道这实际上意味着什么:

List<Integer> list = new ArrayList<Integer>(); //Example 1

为了将此问题与其他问题区分开来,我阅读了有关多态性以及示例 1 和示例 2 之间的区别的帖子,并且我了解示例 1 允许“编程到接口”。我还了解到,通过示例 1,可以轻松地将 list 更改为 LinkedList 而不会影响其余代码。

ArrayList<Integer> list = new ArrayList<Integer>(); //Example 2

但我想知道示例 1 的实际含义。它会创建一个新列表吗?还是它会创建一个新的 ArrayList?结果对象是否具有列表的属性?或者生成的对象是否具有 ArrayList 的属性?我可以实现 ArrayList 在列表上使用的方法而不会出现编译错误吗?

这是我第一次发布问题,所以如果我可以做出任何改进,请告诉我。

【问题讨论】:

标签: java list arraylist


【解决方案1】:

List是接口,ArrayList是List接口的具体实现。

如果你熟悉多态的概念,如果不熟悉,请参考Java Interface (w3schools),或者记住任何实现接口的类都必须重写它的所有抽象方法,以便类获取它的所有方法。

您的List 变量将获得add() 方法,这些&lt; &gt; 比较大括号被指定为“我要添加的列表的对象”。

【讨论】:

    【解决方案2】:

    不属于java,属于OOP:

    当您将对象的引用分配给某个超类型或接口的变量时,对象实际上并没有发生任何事情。您将只能调用变量上声明的类型可见的方法。

    请记住,任何实现接口的类都必须实现所有方法

    【讨论】:

      【解决方案3】:

      假设您有一个接收List 对象作为参数的方法。

      public void myMethod(List<Integer> myList) { ... }
      

      通过使用示例 1,您可以灵活地将 List 接口的不同实现传递给此方法,而无需进行任何类型的转换。

      List<Integer> list1 = new ArrayList<Integer>();
      List<Integer> list2 = new LinkedList<Integer>();
      myMethod(list1);
      myMethod(list2);
      

      【讨论】:

        【解决方案4】:

        在您的两个示例中,只有表达式 new 创建对象实例(= 的右侧),左侧仅定义一个指向您创建的对象的变量。

        在这两种情况下,您创建的对象都是ArrayList 类型。

        List是接口,不是类,接口本身不能实例化。但是ArrayList 实现接口List,因此您可以将ArrayList 的实例分配给List 类型的变量。

        示例 1 的优点是您可以稍后决定创建 List 的另一个实现(如 LinkedList),并且所有使用 List 类型作为变量的代码仍然可以正常工作而无需任何更改。在示例 2 中,如果您稍后决定需要不同类型的 List,则需要更改指向实际对象的所有变量的类型。

        您的问题:

        但我想知道示例 1 的实际含义。是否创造 新名单?还是创建一个新的 ArrayList?

        它会创建一个新的ArrayList

        生成的对象是否具有列表的属性?还是 结果对象具有 ArrayList 的属性?

        生成的对象具有 ArrayList 的所有属性。

        但是,通过List类型的变量list,您只能访问接口List中定义的方法。

        但是您可以使用 type-casting 来访问 ArrayList 中的方法,如果您以后需要的话(但没有什么理由,因为 ArrayList 没有太多超出 List 的内容)

        List<Integer> list = new ArrayList<Integer>(); //Example 1
        ArrayList<Integer> arrayList = (ArrayList<Integer>) list; // type-cast
        

        【讨论】:

        • 感谢您的回答!提到“类型转换”确实澄清了你的答案,这正是我需要听到的。
        【解决方案5】:

        您可能已经知道,List 是一个接口,而 ArrayList 是一个类。这意味着 List 更通用,而 ArrayList 更具体。

        在示例 1 中,您无法调用 ArrayList 支持的其他方法,例如你不能调用 ensureCapacity 因为它是在 Arraylist 类中实现的。

        与示例 2 不同,您可以调用 ArrayList 支持的所有功能。使用示例 1 的好处是增加灵活性并最大限度地减少代码更改以防实现更改,例如将来您决定使用 LinkedList。您无需担心对使用列表变量的所有行进行任何更改。

        【讨论】:

          【解决方案6】:

          通常首选从其实现的接口声明变量,但是根据您使用的接口或抽象类,您可能无法访问某些方法。

          基本上,它可以让您的程序变得更加灵活。

          关于你的问题:

          您的第一个示例声明了 List 并将其初始化为 ArrayList。您将只能从List 接口及其父类/接口调用方法。

          您的第二个示例声明了ArrayList 并将其初始化为ArrayList,这意味着您现在可以访问ArrayList 类中的调用方法,例如ArrayList#ensureCapacityArrayList#trimToSize

          【讨论】:

            猜你喜欢
            • 2015-05-29
            • 1970-01-01
            • 2014-01-03
            • 2011-10-21
            • 1970-01-01
            • 2021-06-04
            • 2019-08-24
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多