声明ArrayList或集合实现类的最佳做法

9

请问有人可以解释一下以下声明 ArrayList 来存储 String 的区别吗?

List type1 = new ArrayList();
List type2 = new ArrayList<String>();
List<String> type3 = new ArrayList<String>();
ArrayList<String> type4 = new ArrayList<String>();
List<String> type5 = null;
ArrayList<String> type6 = null;

那么,以上哪种声明方式是声明一个 ArrayList 字符串的最佳实践方式?为什么?


6个回答

10
第一二个使用原始类型。这意味着您的列表根本不是类型安全的。即使您的意图是要一个字符串列表,编译器也会让您在其中存储整数。编译器将发出警告,您不应忽略它。
第三个是正确的。它告诉编译器你打算使用一个字符串列表,并且你选择的具体实现是ArrayList。如果您改变主意想使用LinkedList,那么只需要更改这行代码。
第四个告诉编译器你的程序不仅需要一个列表,而是需要这个列表是一个ArrayList。如果您的代码确实需要调用特定于ArrayList的方法,并且这些方法不存在于List接口中,那么这是可以的。但在99.9%的情况下,这并不是最佳选择,您应该选择第三个。
最后两个声明变量并将其初始化为null,而不是创建一个列表。这是一种设计上的问题。在使用列表之前,您必须确保它不为null。最好立即使用有效的列表进行初始化,这样更安全。

7
  • List type1 = new ArrayList();
  • List type2 = new ArrayList<String>();

    您有一个 原始类型 ArrayListList,虽然这是合法的代码,但您不应该使用它们:

    ...术语 "unchecked" 意味着编译器没有足够的类型信息来执行所有必要的类型检查以确保类型安全。

  • List<String> type3 = new ArrayList<String>();

    这个是安全的,自Java 7以来,它可以使用钻石操作符并重写为:

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

    这是最好的,因为它是 面向接口编程,意味着您可以将 type3 更改为实现 List 的任何其他类。

  • ArrayList<String> type4 = new ArrayList<String>();

    这是一个具体的对象,您永远不能将 type4 的类型更改为除 ArrayList 之外的其他类型。

最后两个无法与其余内容进行比较,你只是给它们一个默认值,有时你被迫这样做,有时可以跳过此初始化。

2

type1type2属于原生类型,应该避免使用。

type3type4是不错的(但不是最好的,我会回到这个问题上) - 我更喜欢type3而不是type4,因为它使用接口类型(你应该按照接口编程)。例如,你可以使用Arrays.asList("a","b")type3

type5type6type3type4类似,但我建议您避免初始化为null

最后,在Java 7+中,我建议使用钻石操作符。例如:

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

2

一般来说,保持左侧为您需要执行功能的最不具体类型是一个好习惯。但是,您应该始终将可参数化类型参数化,并避免使用原始类型。因此,您应该使用:

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

请注意,从Java 7开始,您还可以省略右侧的类型:
List<String> type3 = new ArrayList<>();

以后如果你希望使用LinkedList代替当前的数据结构,你只需更新创建列表的那行代码,而无需更改所有引用。


2

1和2是原始类型声明。你可以添加任何你喜欢的对象类型到这个列表中,但你无法在编译时保证类型安全性。以这种方式声明列表通常不被赞同,因为很容易犯一个简单的错误,意外地把一个对象放进列表里。真正的警告在于,这个错误直到运行时才会显现出来,而使用类型参数将使这个错误在编译时显现出来,这要容易处理得多。
3是声明列表(或任何类型的集合)的首选方法,因为你是绑定接口而不是具体实现。它还包括类型边界,保证了编译时类型安全。
4是对具体类型ArrayList的声明。如果你需要具体类型,那么这是可以的,但是几乎没有什么情况需要这样做。
5和6分别是3和4的重复;它们的区别在于它们都初始化为null。

1

要么 List<String> type3 = new ArrayList<String>();,要么 List<String> type5 = null;

最好不要使用原始类型,如ListArrayList,声明变量时使用接口类型而不是实现类型更加灵活。

至于你是否想将变量初始化为null并在以后实例化List(或将返回List实例的方法的结果分配给变量),或者在声明时实例化它,我认为这两个选项都是同样有效的。


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