当某个方法将Object []的列表作为输入时,即使在运行时实际输入的是Object的列表,该方法仍然可以使用。问题是,对于Java中的泛型来说,List<something>
的真正含义是什么,List<Object[]>
和List<Object>
之间有什么区别?
/*
* if name is "A", then the input is a List<Object[]>
* if name is "B", then the input actually is a List<Object>
*/
public List<String> convert(List<Object[]> objectList, String name) {
List<String> resultList = new ArrayList<String>();
if (StringUtils.equals(name, "A")) {
for (Object[] object : objectList) {
String code = StringUtils.join((String) object[0], (String) object[1]);
resultList.add(code);
}
return resultList;
}
else if(StringUtils.equals(name, "B")) {
for (Object object : objectList) {
String code = (String) object;
resultList.add(code);
}
return resultList;
}
}
实际上,在运行时,此方法可以正常工作,并且同时使用List<Object[]>
和List<Object>
。
只是想知道任何人都可以对它的工作方式进行一些解释。
答案 0 :(得分:2)
所以要按顺序回答:
对于Java中的泛型来说,List<something>
的真正含义是什么? <>
方括号表示法允许您指定特定的类型您想要的通用类。基本上,List
可以是List<A>
,List<B>
等:其内容可以是任何东西。写List<Q>
表示它是一个List
,其中包含类型为Q
的东西。
List<Object[]>
和List<Object>
有什么区别? []
是数组运算符。 List<Object[]>
是一个包含Object
的数组的列表。 List<Object>
是包含Object
的列表。在Java中,almost everything是Object
,包括数组!
这里还有另一件事要注意:Java泛型很复杂(而且很有趣),并且有一种叫做类型擦除的东西,这意味着在运行时List<Object>
和{{1 }}都变成List<XYZ>
-没有特定的类型!括号中的内容仅在编译时使用-基本上是用来检查您编写的内容是否正确。参见What does angle brackets T mean in Java和Java generics type erasure when and what happens
为什么您的代码运行?好吧,在List
情况下很简单。在运行时,参数只是一个"A"
,但是您的代码希望在该列表中找到List
,并且确实可以。在Object[]
情况下,情况更加复杂:该参数只是一个"B"
,您可以遍历其内容将其处理为List
。这很好,因为如上所述(几乎)所有内容都是Object
。然后,您将那些对象转换为Object
-仅在我们不考虑运行时输入String
未键入的情况下,这很奇怪。就Java而言,该列表中可能有任何内容,您告诉它有List
个。因为输入实际上是String
的列表,所以一切都可以解决。
有趣的一点(您的代码中没有包括)是如何调用一个使用String
和List<Object[]>
的方法,而Java在编译时不会抱怨。