Java List<?> 与 ArrayList<?> 有什么区别?深入比较和常见问题解答
2024-03-21 02:13:02
Java 中 Type List 与 Type ArrayList:深入比较
在 Java 中,List 和 ArrayList 是两个常用的集合类型,它们都用于存储和管理数据。然而,在泛型、协变性和用法方面,它们有一些关键的区别。
泛型类型
- List: List 是一个接口,它接受泛型类型参数,指定集合中元素的类型。例如,
List<String>
表示一个字符串列表。 - ArrayList: ArrayList 是一个具体类,它实现了 List 接口。它是一个动态数组,也接受泛型类型参数。例如,
ArrayList<Integer>
表示一个整数数组。
协变性
协变性是指从父类类型派生的子类类型是否也可以用于父类类型的上下文。
- **List>:** List> 表示一个包含未知类型元素的列表。它可以存储任何类型的元素,但不能从它提取元素(因为编译器不知道元素的类型)。
- **ArrayList>:** ArrayList> 表示一个包含未知类型元素的 ArrayList。它同样可以存储任何类型的元素,但不能从它提取元素。
用法
- **List>:** List> 通常用于需要处理未知类型列表的情况,例如从泛型方法中返回列表。
- **ArrayList>:** ArrayList> 主要用于需要一个动态数组,并且知道数组中元素的类型不需要明确的情况。
何时使用 List<?>
- 当你处理未知类型列表时,例如从泛型方法中返回列表。
- 当你只需要访问列表的方法(例如
size()
和 `isEmpty()),而不关心元素的类型时。
何时使用 ArrayList<?>
- 当你需要一个动态数组,并且知道数组中元素的类型时。
- 当你想避免指定泛型类型,例如在循环中。
实际示例
考虑以下代码:
List<?> unknownList = new ArrayList<Integer>();
这个示例创建了一个包含未知类型元素的列表。我们不能从 unknownList
中提取元素,因为编译器不知道它的类型。
相比之下,下面的代码创建了一个包含整数元素的 ArrayList:
ArrayList<Integer> integerList = new ArrayList<>();
在这个示例中,我们指定了 ArrayList 的元素类型为整数。我们可以从 integerList
中提取元素,因为编译器知道它的类型。
结论
List> 和 ArrayList> 在 Java 中扮演着不同的角色,具体取决于所处理列表的类型信息和所需的操作。了解它们之间的区别将有助于你在项目中有效地选择和使用集合类型。
常见问题解答
Q1. 什么时候我应该使用 List> 而不是 ArrayList>?
A1. 当你处理未知类型列表,并且只需要访问列表的方法时,使用 List<?>。
**Q2. ArrayList> 与 ArrayList extends Object> 有什么区别?** A2. ArrayList> 可以包含任何类型的元素,而 ArrayList<? extends Object> 可以包含任何 Object 或其子类的元素。
**Q3. 为什么不能从 List> 中提取元素?** A3. 因为编译器不知道 List> 中元素的类型,所以它不能确保安全地提取元素。
**Q4. 什么是协变性,它在 List> 中如何使用?** A4. 协变性允许子类类型用于父类类型的上下文。List> 利用协变性来表示一个包含未知类型元素的列表。
**Q5. 什么时候可以使用 ArrayList>?** A5. 当你需要一个动态数组,并且知道数组中元素的类型时,可以使用 ArrayList>。