• 了解Java的自动装箱与拆箱


    一.简单来说,装箱就是自动将基本数据类型转换成包装器类型;拆箱就是自动将包装器类型转换为基本数据类型。

        //自动装箱

         Integer total = 99;

        //自动拆箱

       int totalprim = total;

    需要装箱拆箱的类型有:

     

     

    Integer total = 99; 
    执行上面那句代码的时候,系统为我们执行了: 
    Integer total = Integer.valueOf(99);

    int totalprim = total; 
    执行上面那句代码的时候,系统为我们执行了: 
    int totalprim = total.intValue();

    对于装箱:

    当进行装箱时如果-128<=value<=127时,则会返回已经产生的静态的Inreger数组对象。而其他值则创建一个Integer对象,因此,装箱的过程会创建对应的对象,这个会消耗内存,所以装箱的过程会增加内存的消耗,影响性能。

    对于拆箱:直接返回value值给基本数据类型。

    二. 相关问题:

    上面我们看到在Integer的构造函数中,它分两种情况:

    1、i >= 128 || i < -128 =====> new Integer(i)

    2、i < 128 && i >= -128 =====> SMALL_VALUES[i + 128]

    SMALL_VALUES本来已经被创建好,也就是说在i >= 128 || i < -128是会创建不同的对象,在i < 128 && i >= -128会根据i的值返回已经创建好的指定的对象。

    当面对下面的代码时

            Integer i1 = 100;

            Integer i2 = 100;

            Integer i3 = 200;

            Integer i4 = 200;

            Integer i5=new Integer(100);

            Integer i6=new Integer(100);

     

              System.out.println(i1==i2);  //true

             System.out.println(i3==i4);  //false

      System.out.println(i5==i6);  //false

    从上面的例子可以看出i1和i2会进行自动装箱,并且值在SMALL_VALUES数组中,所以会引用到同一个Integer对象中,所以是相等的,而后面i3和i4则是自己各自创建一个新的对象,所以是不等的,对于i5和i6则是自己创建一个对象,不涉及到装箱和拆箱,所以不相等。

    注意:SMALL_VALUES数组则是只对Integer、Short、Character、Long中存在,而其他的都是默认创建一个新的对象,当进行比较时都不相等。

    对于Boolean类型中,内部已经提前创建好两个对象,所以在进行比较时是相等的。

    三.当基本数据类型与包装类型进行比较时会发生什么情况呢?

     Integer num1 = 400; 

     int num2 = 400; 

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

    说明num1 == num2进行了拆箱操作

     

     Integer num1 = 100; 

     int num2 = 100; 

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

    我们先来看看equals源码:

     @Override

     public boolean equals(Object o) {

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

    }

    我们指定equal比较的是内容本身,并且我们也可以看到equal的参数是一个Object对象,我们传入的是一个int类型,所以首先会进行装箱,然后比较,之所以返回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);

    }

    它必须满足两个条件才为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、当两种不同类型用==比较时,包装器类的需要拆箱, 当同种类型用==比较时,会自动拆箱或者装箱

     

    四.Java 变量参数传入方法,修改后是否影响外面的值

    基本类型:值存放在局部变量表中,无论如何修改只会修改当前栈帧的值,方法执行结束对方法外不会做任何改变;此时需要改变外层的变量,必须返回主动赋值。

    引用数据类型:指针存放在局部变量表中,调用方法的时候,副本引用压栈,赋值仅改变副本的引用。但是如果直接改变副本引用的值,修改了引用地址的对象,此时方法以外的引用此地址对象当然被修改。(两个引用,同一个地址,任何修改行为2个引用同时生效)

    Integer是地址传递,但Integer类中final的value字段,说明一旦Integer类创建之后他的值就不能被修改,例如:

    Integer m=new Integer(1);

    m=6;

    这里的原理是当m引用指向6时,创建了一个新的对象,而m指向了这个新的对象,而这个创建对象的原理是自动装箱原理。

    而对于

    public static void main(String[] args){

        Integer a1 = 5;

        updateInteger(a1);

        System.out.println(a1);

    }

    public static void updateInteger(Integer var){

        var = 10;

    中,则是原理如下所示:当一开始a1和var同时指向5,但是var=10引发自动装箱原理,造成var指向新的对象10,所以对于a1并没有改变值。

    关于String,本质是final类型char数组,不可修改,只能赋值,在做参数传入方法修改时,其实是新建对象,必须返回重新对外面的变量赋值才会对外面的String引用生效。

  • 相关阅读:
    使用jmeter进行接口测试
    jenkins默认插件
    【机器学习】关于PCA 昕
    雲瑞文件直链分享软件
    FOB离岸价
    【数据分享】某地区1959~2019年60年降雨量时间序列数据
    【数据分享】银行客户流失Bank Customer Churn数据
    【数据分享】糖尿病患者研究数据集
    【数据分享】维基百科Wiki负面有害评论(网络暴力)文本数据多标签分类挖掘可视化
    C# Speech
  • 原文地址:https://www.cnblogs.com/xiaobaidashu/p/12096456.html
Copyright © 2020-2023  润新知