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。


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

  • 相关阅读:
    linux下shell显示-bash-4.1#不显示路径解决方法
    update chnroute
    An error "Host key verification failed" when you connect to other computer by OSX SSH
    使用dig查询dns解析
    DNS被污染后
    TunnelBroker for EdgeRouter 后记
    mdadm详细使用手册
    关于尼康黄的原因
    Panda3d code in github
    Python实例浅谈之三Python与C/C++相互调用
  • 原文地址:https://www.cnblogs.com/longestory/p/4566988.html
Copyright © 2011-2022 走看看