List<String> list = new ArrayList<String>() 和 ArrayList<String> list = new ArrayList<String>() 有什么区别?

21

嗨,我对以下两个概念区别不是很清楚,

List<String> list = new ArrayList<String>();

ArrayList<String> list = new ArrayList<String>();

首先,它们是两种不同类型的。 - Burhan Khalid
这个问题之前就被问过了,并且有答案:https://dev59.com/jWkw5IYBdhLWcg3wfKrZ。 - user80755
在第一种类型中,您可以更改List实现以包括Vector、LinkedList等,而不是Arraylist。第二种类型特别创建了一个Arraylist,您将被束缚于此 :) - vikeng21
5个回答

14
List<String> list = new ArrayList<String>();

创建一个字符串类型的列表,该列表可以被潜在地强制转换为任何其他类型的列表。这被称为解耦。您正在将代码从接口的特定实现中解耦。它提供的优势是,在编写大量代码时,可以根据偏好(速度、内存等)在各种类型的列表之间进行切换,因为所有代码都可以将列表视为类型List。您还可以将列表作为参数传递并从函数返回列表。如果以后不满意ArrayList,则只需更改那一行代码即可。

List<String> list = new ArrayList<String>(); // old code
List<String> list = new LinkedList<String>(); // new code

// The rest of the code doesnt need changing

...
list = getList();
...

public List<String> getList() {
  List<String> temporaryList;
  ...
  return temporaryList;
}

public void changeList(List<string> localListVariable) {}

而且您的程序将按预期运行。


另一方面,

ArrayList<String> list = new ArrayList<String>();

创建了一个String类型的ArrayList,它不能用作任何其他类型的List(Vector,LinkedList等)。因此,它受到可用于ArrayList的方法的限制。 如果现在希望更改使用的列表类型,则必须在整个程序中更改所有函数参数和返回类型等内容(无论您何时不得不创建一个ArrayList<String>来使用您的变量)。


4

List<String>ArrayList<String> 的超类(或可能是有效的接口)。将 ArrayList<String> 的实例分配给 List<String> 变量是允许的。这在某种程度上是一种动态转换的形式。当访问 List<String> list 时,只能使用与 List<String> 相关的方法;尽管对象是 ArrayList<String> 的实例,但来自 ArrayList<String> 的方法将被隐藏。


2
关于您获取的内存实例,没有任何区别。然而,按照接口编程被认为是一种良好的实践方式(参见例如什么是“按照接口编程”?)。许多Java API是基于接口定义的,即无论您使用哪个特定接口的实现,功能都可以独立工作。这有助于提高代码清晰度和质量,并降低出现错误的概率,这些错误来自于依赖于某个特定实现类的某些属性(除非这些属性真的很重要)。

1
在这两种情况下,您都会创建ArrayList对象。但是List<String> list = new ArrayList<String>();将使用List<String>的引用来引用对象,而ArrayList<String> list = new ArrayList<String>();将使用类型为ArrayList<String>的引用变量来引用对象。
例如,您可以使用ArrayList<String>的引用调用名为ensureCapacity的方法,但是您不能使用List<String>的引用这样做。
以下内容将编译:
ArrayList<String> list = new ArrayList<String>();
list.ensureCapacity(10);    // This will work

以下代码将无法编译:

List<String> list = new ArrayList<String>();
list.ensureCapacity(10);    // This will not compile

无论哪种情况,您都将创建一个ArrayList对象而不是List对象,尽管ArrayList IS-A List。因此,在这种情况下,List对象和ArrayList对象之间没有任何区别。 - Rahul Bobhate
只是为了完善你的回答:你可以添加强制类型转换,然后第二个示例也将编译成功: List<String> list = new ArrayList<String>(); ((ArrayList<String>) list).ensureCapacity(10); // 这将编译通过。 但是,添加强制类型转换使第二个示例实际上与第一个示例相同。 - Nenad Bulatović

0

ArrayList 会创建一个 ArrayList 类型的对象,而 List 会创建一个 List 类型的对象,ArrayList 是基于 List 接口实现的。如果您不知道什么是接口,请查阅 javadocs。


ArrayList的对象占用的内存空间比List的对象多吗? - user3300570
你不必担心那个。 - rhbvkleef

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接