自动装箱和拆箱从Java 1.5开始引入,目的是将原始类型值自动地转换成对应的对象类型。
什么是自动装箱和拆箱
自动装箱就是Java自动将原始类型值转换成对应的对象,比如将int的变量转换成Integer对象,这个过程叫做装箱,反之将Integer对象转换成int类型值,这个过程叫做拆箱。因为这里的装箱和拆箱是自动进行的非人为转换,所以就称作为自动装箱和拆箱。原始类型byte,short,char,int,long,float,double和boolean对应的封装类为Byte,Short,Character,Integer,Long,Float,Double,Boolean。
自动装箱拆箱要点
- 自动装箱时编译器调用valueOf将原始类型值转换成对象,同时自动拆箱时,编译器通过调用类似intValue(),doubleValue()这类的方法将对象转换成原始类型值
自动装箱的弊端
自动装箱有一个问题,那就是在一个循环中进行自动装箱操作的情况,如下面的例子就会创建多余的对象,影响程序的性能。
上面的代码sum+=i
可以看成sum = sum + i
,但是+
这个操作符不适用于Integer对象,首先sum进行自动拆箱操作,进行数值相加操作,最后发生自动装箱操作转换成Integer对象。其内部变化如下
由于我们这里声明的sum为Integer类型,在上面的循环中会创建将近4000个无用的Integer对象,在这样庞大的循环中,会降低程序的性能并且加重了垃圾回收的工作量。因此在我们编程时,需要注意到这一点,正确地声明变量类型,避免因为自动装箱引起的性能问题。
问题一:装箱拆箱举例
- public class Demo{
- public static void main(String[] args) {
- Integer i = 10;
- int n =i;
- }
- }
Integer localInteger = Integer.valueOf(10);
拆箱通过:
- int i = localInteger.intValue();
问题二、八种基本类型的包装类中的常量池与否
原因:
看看valueOf的源码:-128到128之外,则新建对象。(注释:java1.7源码)
假如面试官只是为了考点是否深入其实到这儿就结束了。碰到一个较真的面试官,可能会一并问这个问题。
示例二:
答案:false,false。
长得几乎一摸一样,只是类型由Integer变成了Double。
是不是想问为什么设计者这么变态?因为常量数量有限,可以通过常量数组去处理加快速度,而类似double,float也用-127到128范围枚举的话就太多了。
总结记住以下:(记少不记多,记住第二句!)
Integer、Short、Byte、Character、Long、Boolean有常量池。
double,float没有常量池。
问题三、衍生的String的问题:
ava中的数据类型,可分为两类:1.基本数据类型,也称原始数据类型。byte,short,char,int,long,float,double,boolean
他们之间的比较,应用双等号(==),比较的是他们的值。
2.复合数据类型(类)
当他们用(==)进行比较的时候,比较的是他们在内存中的存放地址,所以,除非是同一个new出来的对象,他们的比较后的结果为true,否则比较后结果为false。 JAVA当中所有的类都是继承于Object这个基类的,在Object中的基类中定义了一个equals的方法,这个方法的初始行为是比较对象的内存地 址,但在一些类库当中这个方法被覆盖掉了,如String,Integer,Date在这些类当中equals有其自身的实现,而不再是比较类在堆内存中的存放地址了。
对于复合数据类型之间进行equals比较,在没有覆写equals方法的情况下,他们之间的比较还是基于他们在内存中的存放位置的地址值的,因为Object的equals方法也是用双等号(==)进行比较的,所以比较后的结果跟双等号(==)的结果相同。
- public class Demo{
- public static void main(String[] args) {
- String s1 = new String("hello");
- String s2 = new String("hello");
- System.out.println(s1 == s2);//输出false
- System.out.println(s1.equals(s2));//输出true
- String s3 = "hello";
- String s4 = "hello";
- System.out.println(s3 == s4);//输出true
- System.out.println(s3.equals(s4));//输出true
- }
- }
1 public class TestString { 2 public static void main(String[] args) { 3 String s1 = " Monday " ; 4 String s2 = " Monday " ; 5 if (s1 == s2) 6 { 7 System.out.println( " s1 == s2 " );} 8 else { 9 System.out.println( " s1 != s2 " );} 10 } 11 }