我在写Android项目的时候,估计写的最熟练的词是:Listlist=newArrayList();list.add(1);//向集合中添加一个整数inti=list.get(0);//从集合中获取元素 ArrayList就是这么好用!当时只知道尖括号<>只能加大写字母开头的Object类型,不能加int、char、double等原始类型。 但随着逐渐厌倦“码农”这种无脑学习方式,我开始重新审视Java代码的内部结构。 首当其冲的就是每一项都必须使用的ArrayList。在我的另一篇博客中,对ArrayList的源码实现做了一个大致的分析。不过在源码中还有一些看不到的问题,确实有疑问,急需解决。列表<整数>列表=newArrayList<整数>();这段代码中的每个元素都是Integer类型,所以在列表中添加新元素时,必须是Integer,比如添加String,代码Wire下方会出现红色波浪。但是list.add(1)这句话众所周知,如果你在代码中写了一个没有小数点的数字,它就是一个int;给一个只能包含Integer的List添加一个int也不会报错,你不觉得很坑爹吗?同理,inti=list.get(0),取list中index为0的元素应该也是In??teger,为什么接收到的变量是int?多么明显的类型不匹配错误!之前听说过“包装类”这个概念,但是我忽略了,因为我一直认为Integer和Float之类的东西是在装丑,只是因为List不接受int和float类型。我不得不发明Integer和Float,但它们实际上没有用。我最近读了《Effective Java》中的一个部分,叫做“Preferprimitivetypestoboxedprimitives”。混合原始类型和包装类型的例子很多,看得我头晕目眩。下面是一段代码:Longsum=0L;for(longi=0;ili){intsum=0;for(Integeri:li)if(i%2==0)sum+=i;returnsum;}在循环体中做了两次拆箱操作,编译器会将其转化为如下代码:publicstaticintsumEven(Listli){intsum=0;for(Integeri:li)if(i.intValue()%2==0)sum+=i.intValue();返回总和;}Integer的intValue方法就简单多了,直接返回包装后的int值@OverridepublicintintValue(){returnvalue;//value是Integer的成员变量}自动拆箱的使用刚好和自动装箱相反,也用在参数传递和赋值的过程,这里就不赘述了。我们再分析一下那段超级低效的代码。自动拆箱和转换后应该是这样的:Longsum=Long.valueOf(0L);for(longi=0;i