为什么我们需要 Java 中的纯 <?>?
why do we need the pure <?> in Java?
为什么我们需要 Java 中的纯 <?>
?
传递的任何东西都只能用作 Object 吗?所以它与任何 class 转换为 Object 一样有用(只有 9 种方法可用)
谢谢
我的意思是,如果你有 List< ? > 列表,您只能将项目用作对象。这意味着 list.get(0) 给你对象,仅此而已。是的,我也可以在那里存储任何东西,但是它对你有用吗?这就像你有一件好东西,一件昂贵的东西,却把它扔进了垃圾桶。你只能从垃圾桶里得到垃圾。同样,您可以将任何 class 的任何好对象放入 List,但仅使用 9 种方法从那里获取对象。
无界通配符在两种情况下是一种有用的方法:
如果您编写的方法可以使用 Object
class 中提供的功能来实现。
当代码使用不依赖于类型参数的泛型 class 中的方法时。
例如,List.size
,或 List.clear
。事实上,Class<?>
之所以如此常用,是因为 Class<T>
中的大多数方法都不依赖于 T
.
例如见Collections.swap
方法:
public static void swap(List<?> list, int i, int j) {
final List l = list;
l.set(i, l.set(j, l.get(i)));
}
知道类型无助于交换 List
中的两个元素,因此使用了无限通配符。您传入一个 List
- 任何 List
- 该方法交换索引元素。无需担心类型参数。
有关详细信息,请参阅:Unbounded Wildcards.
我认为最好的答案是因为有时你根本不知道 class 参数化的类型。正如迈克尔指出的那样 List<?>
与 List<Object>
不同。所以?
提供了不同的语义,这对保证程序的正确性很有用。
考虑两个列表。一个列表是 List<String>
,另一个是 List<Integer>
。两者都是 Object
,但我们仍然不想将它们混淆。我们不想将 String
放入 Integer
列表中,反之亦然。所以如果你有一个声明为 List<?>
的类型,你就不能安全地将任何类型放入该列表中。 ?
可能是 String
或 Integer
,但您不知道它是什么,而且您不想混淆它们,所以您不能输入任何一个。
OTOH,List<Object>
只是一个对象列表,因为您声明它包含任何对象,所以您可以安全地将 String
和 Integer
都放在列表中。你说你不关心通过声明类型 Object
进入列表的内容,所以任何类型都可以。在我能想到的任何有意义的方式中,List<Object>
都等同于原始类型。这是一个您自己管理的列表,无需编译器的帮助。
为什么我们需要 Java 中的纯 <?>
?
传递的任何东西都只能用作 Object 吗?所以它与任何 class 转换为 Object 一样有用(只有 9 种方法可用)
谢谢
我的意思是,如果你有 List< ? > 列表,您只能将项目用作对象。这意味着 list.get(0) 给你对象,仅此而已。是的,我也可以在那里存储任何东西,但是它对你有用吗?这就像你有一件好东西,一件昂贵的东西,却把它扔进了垃圾桶。你只能从垃圾桶里得到垃圾。同样,您可以将任何 class 的任何好对象放入 List,但仅使用 9 种方法从那里获取对象。
无界通配符在两种情况下是一种有用的方法:
如果您编写的方法可以使用
Object
class 中提供的功能来实现。当代码使用不依赖于类型参数的泛型 class 中的方法时。
例如,List.size
,或List.clear
。事实上,Class<?>
之所以如此常用,是因为Class<T>
中的大多数方法都不依赖于T
.
例如见Collections.swap
方法:
public static void swap(List<?> list, int i, int j) {
final List l = list;
l.set(i, l.set(j, l.get(i)));
}
知道类型无助于交换 List
中的两个元素,因此使用了无限通配符。您传入一个 List
- 任何 List
- 该方法交换索引元素。无需担心类型参数。
有关详细信息,请参阅:Unbounded Wildcards.
我认为最好的答案是因为有时你根本不知道 class 参数化的类型。正如迈克尔指出的那样 List<?>
与 List<Object>
不同。所以?
提供了不同的语义,这对保证程序的正确性很有用。
考虑两个列表。一个列表是 List<String>
,另一个是 List<Integer>
。两者都是 Object
,但我们仍然不想将它们混淆。我们不想将 String
放入 Integer
列表中,反之亦然。所以如果你有一个声明为 List<?>
的类型,你就不能安全地将任何类型放入该列表中。 ?
可能是 String
或 Integer
,但您不知道它是什么,而且您不想混淆它们,所以您不能输入任何一个。
OTOH,List<Object>
只是一个对象列表,因为您声明它包含任何对象,所以您可以安全地将 String
和 Integer
都放在列表中。你说你不关心通过声明类型 Object
进入列表的内容,所以任何类型都可以。在我能想到的任何有意义的方式中,List<Object>
都等同于原始类型。这是一个您自己管理的列表,无需编译器的帮助。