标签:rdp lease contain 开始 惊奇 链接 基本 基本类型 封装
本文由 ImportNew - 飘扬叶 翻译自 mlangc。欢迎加入翻译小组。转载请见文末要求。
不幸的是并不是每件事都尽如人意。举个例子,现在将一个Java数组转换为List。当然,我们可以使用Arrays.asList方法,但是如果没有慎重思考就随便使用几乎肯定会产生令人讨厌的意外。考虑完下面这段程序并预测其输出你就明白我的意思了:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
package com.wordpress.mlangc.arrays; import java.util.Arrays; public class ArraysToList { public static void main( final String[] args) { System.out.println( Arrays.asList( new String[] { "a" , "b" })); System.out.println( Arrays.asList( new Integer[] { 1 , 2 })); System.out.println( Arrays.asList( new int [] { 1 , 2 })); System.out.println( Arrays.asList( new String[] { "a" , "b" }, "c" )); } } |
由于Javadoc对Arrays.asList的说明相当模糊,对你来说预测出程序的运行结果可能有点困难,下面我们来一步步的揭晓答案:
但是发生了什么呢?前两个打印语句与我们预期的结果相同,因Java语言规范规定了调用一个声明为foo(T… t)的方法,比如foo(new T[]{bar,baz})等同于foo(bar,baz)这样的调用。在Arrays.asList方法中T是参数类型,因此它必须为一个Object 类型,但是int不是,而int[]却是。这就是为什么第16行的声明等同于 Arrays.asList(new Object[] { new int[] { 1, 2 } })。
1
|
Arrays.asList( new Object[] { new int [] { 1 , 2 } }) |
最后也是非常重要的一点,在第19行的声明从一开始就产生了调用问题。我们告诉编译器我们需要一个包含String数组和字符串的list,正如我们预期的那样我们得到了我们想要的东西。
到现在为止解释了这么多,但是我们还可以从中学到更多的东西:问题的真正来源并不是可变参数设计的很糟糕;相反的我认为这个设计很好。关于这个问题在《Effective Java2》第 42项规范中已经解释地很清楚了,Arrays.asList违反了该项规范,事实上Arrays.asList作为一个反面教材,告诉了我们在使用Java的可变参数设计API时为什么要非常小心。在这里我不会再重复那篇文章里的回答,但是你自己确实需要亲自去读一下它,但是考虑到完整性我必须指出 上面有问题的声明在使用Java1.4的编译器下编译的时候就会报错,这是相当好的。现在我们仍然会使用Arrays.asList,但是为了安全要求我 们知道所面临的问题的复杂性。下面是在将数组转换为lists的时候我们需要遵循的规则,做到这些可以确保没有任何意外的情况发生:
1
|
List<Integer> list = Arrays.asList(ArrayUtils.toObject( new int [] { 1 , 2 })); |
1
|
List<String> list = Arrays.asList( new String[] { "a" , "b" }); |
不要忘了告诉和你一起工作的人以确保他们不和你犯同样的错误。当然,你也可以选择仅仅记住那些使用Arrays.asList方法时可能出现问题的地方,并使用普通的for循环来代替,但是那会使你的代码很杂乱,还会带来性能方面的问题。
原文链接: mlangc 翻译: ImportNew.com - 飘扬叶
译文链接: http://www.importnew.com/14996.html
标签:rdp lease contain 开始 惊奇 链接 基本 基本类型 封装
原文地址:http://www.cnblogs.com/GarfieldEr007/p/7082943.html