在Java中的==与equals中说到编译器自动为我们加上valueOf这个方法,加上valueOf方法的过程,就是Java中经常说的装箱过程。
Java中一共有四类八种基本数据类型,除掉这几种类型,其它的都是对象,也就是引用类型。在JDK1.5中,给这四类八种基本类型加入了包装类,对应如下:
类型 | 基本类型 | 包装类型 |
整型 | byte | Byte |
short | Short | |
int | Integer | |
long | Long | |
浮点型 | float | Float |
double | Double | |
逻辑型 | boolean | Boolean |
字符型 | char | Character |
再看如下代码:
1 | public static void main(String[] args) { |
编译后打开class文件:
1 | public static void main(String[] args) { |
可以看出来,当我们变量声明为对象类型而赋值为基本数据类型时,Java编译器会对我们的基本数据类型进行装箱,而我们的变量声明为基本类型赋值为对象类型时,编译器又会对我们的对象类型进行拆箱处理。用valueOf作为装箱方法,拆箱方法就各自表述,一般都是基本数据类型加上Value做为拆箱方法,如intValue,longValue,booleanValue等等。
将int的变量转换成Integer对象,这个过程叫做装箱,反之将Integer对象转换成int类型值,这个过程叫做拆箱。以上这些装箱拆箱的方法是在编译成class文件时自动加上的,不需要程序员手工介入,因此又叫自动装箱/拆箱。
已经有了基本类型,为什么还要用包装类?
- 对象是对现实世界的模拟(一切事物皆对象,通过面向对象的方式,将现实世界的事物抽象成对象),在现实中,假设我们去一个系统(数据库)里查询学生李四的年龄,如下图:
这时候,录入员还没给李四录入年龄这一项,如果我们用int来声明年龄,大家都知道int是要初始化的,默认情况下为0,0是什么意思,没出生吗?(当然也可以用-1来表示未录入,但总感觉有点怪怪的),如果用Integer来表示,就没这个问题了,为null,就是未录入。
- 为泛型提供了支持:
1 | public static void main(String[] args) { |
- 提供了丰富的属性和API:
public static void main(String[] args) {
System.out.println(Integer.MAX_VALUE);//打印int能表示的最大值
System.out.println(Integer.MIN_VALUE);//打印int能表示的最小值
System.out.println(Integer.max(12, 13));//找出传入参数的大值
System.out.println(Integer.min(12, 13));//找出传入参数的小值
System.out.println(Integer.sum(12, 13));//求和
System.out.println(Integer.valueOf("123"));//转换字符串为Integer类型
System.out.println(Integer.compare(12, 54));//比较参数大小,返回-1,代表第一个参数小于第二个参数
/**
* 这种方式是可以写的,因为会在编译时解包处理后比较值 new Integer(180).intValue() < new Integer(180).intValue()
*/
System.out.println(new Integer(180) < new Integer(180));
System.out.println(new Integer(180).equals(new Integer(180)));//比较是否相等,推荐写法equals
System.out.println(new Integer(180) == new Integer(180));//==是比较两个对象指向的引用是否一致,不能用来比较值是否相等,此处会返回false
}
下面分析一下不同的声明方式在内存中的展现,代码如下:
public static void main(String[] args) {
int int1 = 180;
Integer int2 = new Integer(100);
}
表现如下图:
参考资料:
清浅池塘 Java自动装箱/拆箱