区分String-list和String [] - 列表与单个元素

时间:2016-08-17 18:24:16

标签: java casting

我正在使用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 [] - 列表?

2 个答案:

答案 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个解决方案。

  1. 使用单个外部元素显式初始化二维数组:

    List<String[]> l4 = Arrays.asList(new String[][] {{"a", "b", "c"}})
    
  2. 使用显式类型参数调用方法,因此编译器知道将您的参数解释为单个元素:

    List<String[]> l4 = Arrays.<String[]>asList(new String[] {"a", "b", "c"})