我正在使用Arrays.asList构建列表。有时是String列表,有时是String []列表。
现在我想问题是尝试区分从String []构建的String-list和带有单个String []的string [] - list。
当然,如果我不必转换为Object并返回,问题就不会很好。
这里有一个小小的片段来澄清会发生什么:
public static void main(String[] args) {
List<String> l1 = Arrays.asList("a", "b", "c");
System.out.println("l1 "+l1);
System.out.println("String.class.isInstance(l1.get(0)) : "+String.class.isInstance(l1.get(0)));
List<String> l2 = Arrays.asList(new String [] {"a", "b", "c"});
System.out.println("l2 "+l2);
System.out.println("String.class.isInstance(l2.get(0)) : "+String.class.isInstance(l2.get(0)));
List<String[]> l3 = Arrays.asList(new String [] {"a", "b", "c"}, new String [] {"a", "b", "c"});
System.out.println("l3 "+l3);
System.out.println("String.class.isInstance(l3.get(0)) : "+String.class.isInstance(l3.get(0)));
//List<String[]> l4 = Arrays.asList(new String [] {"a", "b", "c"});
Object l4 = Arrays.asList(new String [] {"a", "b", "c"});
System.out.println("l4 "+l4);
System.out.println("String.class.isInstance(l4.get(0)) : "+String.class.isInstance(((List<String[]>)l4).get(0)));
}
输出结果为:
l1 [a, b, c]
String.class.isInstance(l1.get(0)) : true
l2 [a, b, c]
String.class.isInstance(l2.get(0)) : true
l3 [[Ljava.lang.String;@15db9742, [Ljava.lang.String;@6d06d69c]
String.class.isInstance(l3.get(0)) : false
l4 [a, b, c]
String.class.isInstance(l4.get(0)) : true
仔细观察最后一行:l4是作为一个对象构建的,但肯定是一个String-list。但是,尝试强制转换为String [] - 列表会传递编译和执行。当然,我会尝试将String用作String []。
2个问题: - 不应该在运行时最后一次打击? - 我应该如何更改l4初始化以获取带有单个项目的String [] - 列表?
答案 0 :(得分:1)
这里有几件事情。
不应该在运行时持续打击?
嗯,不,因为JVM不知道参数化类型:List<String[]>
,它只知道给定的引用可以在运行时 downcast 并且因为它确实可以做到这一点(毕竟它 一个List
)并且因为第0个元素是一个字符串,所以它很乐意取消引用它并在其上调用.toString()
。 / p>
javac
编译器试图告诉您,您正在做的事情可能不是类型安全的。如果您编译了最后一行,javac
会在该行上显示以下警告:
warning: [unchecked] unchecked cast
System.out.println("String.class.isInstance(l4.get(0)) : " +
String.class.isInstance(((List<String[]>) l4).get(0)));
^
required: List<String[]>
found: Object
当您尝试将引用转换为参数化类型时,JVM始终会为您提供未经检查的强制转换警告。
另请注意,方法asList
是(所谓的) varargs 方法。您传递的数组被视为多个参数的序列。
不要这样做(混合数组和列表)。
如何更改l4初始化以获取带有单个项目的String [] - 列表?
List<String[]> l5 = new ArrayList<>();
l5.add(new String[]{"a", "b", "c"});
System.out.println("String[].class.isInstance(l5.get(0)) : " +
String[].class.isInstance(l5.get(0)));
打印:
String[].class.isInstance(l5.get(0)) : true
答案 1 :(得分:0)
我不会在这里回答第一个问题,因为之前已经多次回答过。但至于你关于如何将单个String[]
元素传递给Arrays.asList()
的第二个问题,我可以想到2个解决方案。
使用单个外部元素显式初始化二维数组:
List<String[]> l4 = Arrays.asList(new String[][] {{"a", "b", "c"}})
使用显式类型参数调用方法,因此编译器知道将您的参数解释为单个元素:
List<String[]> l4 = Arrays.<String[]>asList(new String[] {"a", "b", "c"})