zoukankan      html  css  js  c++  java
  • [Java5新特性]自动装箱/拆箱

    自动装箱/拆箱概述

    Java中具有基本类型(int,double,float,long,boolean,char,byte,short)和基本类型包装类(Integer,Double,Float,Long,Boolean,Char,Byte,Short),我们实现基本类型与包装类之间的转换基本有两种方式:

    • 一种为JDK5之前的方式,比如Integer i = Integer.valueof(5);(这里5为基本类型int,Integer包装类利用valueof()方法将其转换为Integer类型)或者int i = i.intValue();(这里基本类型利用intValue()方法将Integer类型转换为基本类型int)。
    • 一种为JDK5之后的方式,比如①Integer i = 5;或者②int i = new Integer(100);,这里基本类型与包装类之间可直接操作,而①的操作就是自动装箱,②的操作就是自动拆箱。

    自动装箱/拆箱原理

    如果我们现在使用第二种方式进行直接赋值操作,代码如下:

    public class Demo {
        @Test
        public void demo() {
            Integer integer = 5;
    
            int i = new Integer(100);
        }
    }
    

    编写完成的Java文件,在运行之前会被编译成Class文件。现在我们将编译后的Class文件,进行反编译操作,得到如下代码内容:

    public class Demo {
        @Test
        public void demo() {
            Integer integer = Integer.valueOf(5);
    
            int i = new Integer(100).intValue();
        }
    }
    

    通过查看反编译的代码内容,我们得知在Java文件编译后的内容与第一种方式的操作保持一致。这就说明实际上Java中基本类型与包装类之间的转换,在JDK5之后不再由我们手动操作,而是由Java编译器帮助我们来完成,与Java的虚拟机是没有任何关系的。

    底层原理分析

    到目前为止,我们已经基本掌握了Java5的自动装箱与拆箱的内容。在实际开发中,目前基本使用的都是Java5之后的版本,所以自动装箱与拆箱内容就不是那么重要了。
    下面我们来看一个例子:

    public class Demo {
        @Test
        public void demo2() {
            Integer i1 = 100;
            Integer i2 = 100;
            boolean b1 = i1 == i2;
            System.out.println(b1);     //output    true
    
            Integer i3 = 200;
            Integer i4 = 200;
            boolean b2 = i3 == i4;
            System.out.println(b2);     //output    false
        }
    }
    

    在上面的例子中,变量Integer类型的i1,i2,i3和i4都是自动装箱,但是最终比较的结果却一个为true一个为false。这让我们比较困惑,原因是什么呢?下面我们来还原一下自动装箱,上面的代码可以改写成如下方式:

    public class Demo {
        @Test
        public void demo3() {
            Integer i1 = Integer.valueOf(100);
            Integer i2 = Integer.valueOf(100);
            boolean b1 = i1 == i2;
            System.out.println(b1);     //output    true
            Integer i3 = Integer.valueOf(200);
            Integer i4 = Integer.valueOf(200);
            boolean b2 = i3 == i4;
            System.out.println(b2);     //output    false
        }
    }
    

    通过改写之后的代码,我们发现原来是Integer类型的valueOf()方法接收100和200返回的内容是不一样的。那我们就需要看查看一下Integer类型的valueOf()方法的源代码,它到底是怎么样的。

    public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }
    

    通过查看源代码我们发现,在Integer类的内部缓存了-128至127之间的256个Integer对象,如果valueOf()方法将这个范围的int类型整数转换成Integer对象时,会直接返回缓存中的内容,否则返回重新创建的Integer对象。
    所以,在上面的例子中,整数100在Integer类的缓存之中,所以直接返回缓存内容。而整数200不在Integer类的缓存之中,所以需要重新创建Integer对象返回。而两个Integer类型的对象做比较,是判断对象地址是否相同,所以一个结果为true一个结果为false。


    转载说明:请注明本文作者及原文连接,谢谢!

  • 相关阅读:
    centos升级glibc(升级到 2.17版)
    访问zabbix首页无法正常登陆
    解决zbx的web界面zabbix服务器端运行中 显示为不(启动命令)
    4. 日期
    3. 页面滚动条位置恢复
    2. 添加版本号
    1. webpack 复制文件
    4. git log的常见用法
    3. git获取历史版本
    2. Git-命令行-删除本地和远程分支
  • 原文地址:https://www.cnblogs.com/longestory/p/4566988.html
Copyright © 2011-2022 走看看