java中 的Boolean、Short、Integer、Long、Float、Double类被称为数值型基本类型的打包类。为什么叫做打包类呢?
因为我们有时候想让基本类型像对象一样操作(对象可以提供更多的信息),就需要使用它们来打包(wrap)java基本类型。这些类的主要目的就是提供对象实例作为壳,将基本类型打包在对象之中,这样就可以操作这个对象,就像是将基本类型当做对象操作。
Java中这些包装类有8种,基础数据类型与它们对应的包装类见下图
基本类型的包装类的使用方法为使用new创建包装类,再传入相应的基本类型的数据,如
Integerintwrap = new Inter(data)
Java中基础数据类型与它们的包装类进行运算时,编译器会自动帮我们进行转换,转换过程对程序员是透明的,这就是装箱和拆箱。装箱就是自动将基本数据类型转换为包装器类型;拆箱就是自动将包装器类型转换为基本数据类型。
当基础类型与它们的包装类有如下几种情况时,编译器会自动帮我们进行装箱或拆箱。
Java中基础数据类型与它们的包装类进行运算时,编译器会自动帮我们进行转换,转换过程对程序员是透明的,这就是装箱和拆箱。装箱就是自动将基本数据类型转换为包装器类型;拆箱就是自动将包装器类型转换为基本数据类型。
当基础类型与它们的包装类有如下几种情况时,编译器会自动帮我们进行装箱或拆箱。
• 进行 “=”赋值操作,会进行装箱或拆箱操作,具体因左侧类型声明而异,如,
Integer num1=99;
Integer num2=1;
int total=num2;
执行上面那句代码的时候,系统为我们执行了:
Integer total = Integer.valueOf(99);
而valueOf源码为
public static Integer valueOf(int i) {
return i >= 128 || i < -128 ? new Integer(i) : SMALL_VALUES[i + 128];
}
其中,
private static final Integer[] SMALL_VALUES = new Integer[256];
它是一个静态的Integer数组对象,也就是说最终valueOf返回的都是一个Integer对象。对于Integer,在(-128,128]之间只有固定的256个值,所以为了避免多次创建对象,事先就创建好一个大小为256的Integer数组SMALL_VALUES,所以如果值在这个范围内,就可以直接返回我们事先创建好的对象就可以了,它被称为常量池。
实际上,Short、Byte、Character、Long这几个类的valueOf方法的实现是类似的。
而Double、Float的valueOf方法的实现是类似的。但它们每次都返回不同的对象。
public static Double valueOf(double d) {
return new Double(d);
}
这里可以用instanceof是关键字判断一个对象是否是另一个对象的实例,如
System.out.println(num1 instanceof Integer); //true
可见,装箱的过程会创建对应的对象,这个会消耗内存,所以装箱的过程会增加内存的消耗,影响性能。
执行下面那句代码的时候,系统为我们执行了:
int total = num1.intValue();
其中,intValue源码为
@Override
public int intValue() {
return value;
}
• 进行+,-,*,/混合运算,会进行拆箱操作,如
System.out.println(num1+num2); //100
System.out.println(num1+num2 instanceof Integer); // error: unexpected type
• 进行>,<比较运算,会执行拆箱操作
System.out.println(num1>total); //true
• 调用equals进行比较,会执行拆箱操作,使用“==”比较,会进行封箱操作
大多数程序设计语言中,使用“==”运算符来判断两个变量是否相等。在java中,使用“==”需要注意运算符两边的类型。
当==用于基本类型时,是比较两个变量存储的值是否相等。但在比较两个对象的时候,则是在比较两个引用变量是否引用的是同一个对象。因为“=”的意思是将某个变量名绑定到某个对象,而==是比较两个变量名是否绑定到同一对象。
如对于如下两行代码
Integer num1=300;
Integer num2=300;
300在转为Integer对象时会new一个对象出来。因为它们不在常量池中,所以是两个不同的对象
System.out.println(num1==num2); //false
而equals则是判断两个对象的值是否相等。
System.out.println(num1.equals(num2)); //true
如果改写代码为
Integer num1=100;
Integer num2=100;
因为100经包装后,放入常量池中,所以有
System.out.println(num1==num2); //true
如果在java中创建对象显式使用关键字new创建对象,如
Integer a = new Inter(100)
Integer b = new Inter(100)
我们看到该关键字,就知道建立了一个新对象,这时它们是两个不同的对象,因为它们不会存放在常量池中,
System.out.println(num1==num2);// false
• ArrayList,HashMap等集合类 添加基础类型数据时,执行装箱操作
网友评论