2022-05-07 11:41

装箱和拆箱-简单记述

Bigmouse

JavaEE

(495)

(0)

收藏

原文链接:https://blog.csdn.net/belongtocode/article/details/102967678

 

一、什么是自动装箱和拆箱:

       简单理解:装箱就是自动将基本数据类型转换为包装器类型,拆箱就是自动将包装器类型转化为基本类型

在Java SE5之前,如果要生成一个数值为10的Integer对象,必须这样进行:

Integer i=new Integer(10);

而在从Java SE5开始就提供了自动装箱的特性,如果要生成一个数值为10的Integer对象,只需要这样就可以了:

Integer i=10;

这个过程会自动根据数值的类型创建Integer对象,则就是自动装箱,同理:

Integer i=10;int j=i;

上面的代码则是自动拆箱,将Integer对象自动拆箱为int

       Java1.5开始的自动装箱和拆箱机制其实是编译时自动完成的,装箱阶段自动替换为valueOf()方法,拆箱阶段自动替换为xxxValue()方法

二、装箱和拆箱是如何实现的:

       java装箱过程是调用包装类的valueOf方法实现,而拆箱过程则是调用包装类的xxxValue方法实现(xxx代表对应的基本类型)

需要装箱拆箱的类型有哪些

image.png

image.png

简单归类:

Integer派别:Integer、Short、Byte、Character、Long这几个类的valueOf方法的实现是类似的,参数在-128~127之间的值时直接返回内部缓冲池中已经存在对象的引用,参数是其他范围时返回新建对象。

Double派别:Double、Float的valueOf方法的实现是类似的。每次都返回不同的新建对象。因为某个范围的整数个数是一定的,而浮点数不是。

Boolean派别:valueOf()每次返回相同的对象

下面对Integer派别进行一个总结,如下图:

image.png

三、代码举例:

Integer num1 = 400; 

int num2 = 400; 

System.out.println(num1 == num2); //true

说明num1 == num2进行了拆箱操作,会将num1执行intValue操作再进行比较

 

Integer num1 = 100; 

int num2 = 100; 

System.out.println(num1.equals(num2));  //true

 

我们先来看看equals源码:

public boolean equals(Object obj) {

        if (obj instanceof Integer) {

            return value == ((Integer)obj).intValue();

        }

        return false;

    }

我们指定equal比较的是内容本身,并且我们也可以看到equal的参数是一个Object对象,我们传入的是一个int类型,所以首先会将num2进行装箱成Integer,然后比较,比较的时候再将其拆箱intValue比较,之所以返回true,是由于它比较的是对象里面的value值。

 

Integer num1 = 100; 

 int num2 = 100; 

 Long num3 = 200L; 

 System.out.println(num1 + num2);  //200

 System.out.println(num3 == (num1 + num2));  //true

 System.out.println(num3.equals(num1 + num2));  //false

1、当一个基础数据类型与封装类进行==、+、-、*、/运算时,会将封装类进行拆箱,对基础数据类型进行运算。

2、对于num3.equals(num1 + num2)为false的原因很简单,我们还是根据代码实现来说明:

@Override

 public boolean equals(Object o) {

  return (o instanceof Long) && (((Long) o).value == value);

 }

 

equals它必须满足两个条件才为true, 而==不用,会拆箱对基础类型进行运算

1、类型相同

2、内容相同

上面返回false的原因就是类型不同。

Integer num1 = 100;

 Ingeger num2 = 200;

 Long num3 = 300L;

System.out.println(num3 == (num1 + num2)); //true

 

总结:

1、需要知道什么时候会引发装箱和拆箱

2、装箱操作会创建对象,频繁的装箱操作会消耗许多内存,影响性能,所以可以避免装箱的时候应该尽量避免。

3、equals(Object o) 因为原equals方法中的参数类型是封装类型,所传入的参数类型(a)是原始数据类型,所以会自动对其装箱,反之,会对其进行拆箱

4、当两种不同类型用= = 比较时,包装器类的需要拆箱, 当同种类型用==比较时,会自动拆箱或者装箱

5.装箱就是执行valueof方法创建integer对象,在-128-127会直接返回cache的常量,其他范围会创建新的对象;自动将基本数据类型转换为包装器类型;

6.= =(或者其他算术类型的运算时)在两个Integer进行比较的时候,首先判断是不是在缓存池中,是则相等

在一个Integer 一个int时,Integer会进行拆箱,所以(Integer a=400 )= = (int a=400)

equals比较时,要同时比较内容value和类型!


0条评论

点击登录参与评论