面试时被问到这个问题,毫无疑问,这个问题,如果没有研究过的话,对于一个应届生来说,是答不上来的。最后面试官给出的答案是自动装箱/拆箱,但是,这个答案感觉不像是缺陷,更像是我们在程序开发过程当中应当注意的一些细节问题。并且这个“缺陷”的源头不在集合框架,而在于自动装箱拆箱其本身。
JDK1.5引入了一些新的特性,这些特性如下:
• 泛型编程 – 提供集合对象的编译时安全类型检查。
• 增强 for 循环 - 编程更容易,去掉了修正了导致迭代出错的问题。
• 装箱/拆箱 - 原始类型(int)和封装类型(Integer)的转换更容易。
• 类型安全的枚举 – 提供了最常使用的类型安全的枚举模式。(Effective Java, Item 21)
• 静态导入Static import - Lets you avoid qualifying static members with class names, without the shortcomings of the Constant Interface antipattern (Effective Java, Item 17).
• Metadata – 避免编写描述信息的代码,实现“声明”编程的模式。程序员声明需要做什么,然后由相关的工具来完成具体的工作。
但是因为集合类当中使用了泛型,同时,因为泛型的缘故,其只能存放引用类型数据,而无法存放值类型数据。如果同时使用了泛型,放入值类型,那么集合类将自动执行自动装箱拆箱操作。这个,是我们需要注意的地方。
测试代码如下:
package com.yang.test; import java.util.ArrayList; import java.util.List; public class BoxTest{ public static void main(String[] args) { int size = 1000000; testInteger(size); testInt(size); testString1(size); testString2(size); } public static void testInteger(int n) { List<Integer> list = new ArrayList<Integer>(); long start = System.currentTimeMillis(); for (int i = 0; i < n; i++) { list.add(i); } long end = System.currentTimeMillis(); System.out.println("testInteger use time is: " + (end - start) + "ms"); } public static void testInt(int n) { List list = new ArrayList(); long start = System.currentTimeMillis(); for (int i = 0; i < n; i++) { list.add(i); } long end = System.currentTimeMillis(); System.out.println("testInt use time is: " + (end - start) + "ms"); } public static void testString1(int n) { List<String> list = new ArrayList<String>(); long start = System.currentTimeMillis(); for (int i = 0; i < n; i++) { list.add(i+""); } long end = System.currentTimeMillis(); System.out.println("testString1 use time is: " + (end - start) + "ms"); } public static void testString2(int n) { List list = new ArrayList(); long start = System.currentTimeMillis(); for (int i = 0; i < n; i++) { list.add(i+""); } long end = System.currentTimeMillis(); System.out.println("testString2 use time is: " + (end - start) + "ms"); } }测试结果如下:
List<String>与List_String的对比说明,在泛型对于String的影响是可以忽略不计的,因为其没有进行装箱操作。
而List<Integer>与List_int之间的对比说明,使用了泛型之后,对List<Integer>进行插入操作时,进行了装箱操作,而没有使用泛型的List_int,因为其没有装箱操作,在时间上会比使用了泛型的List<Integer>更有优势。