[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。



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

时间: 2024-12-15 22:53:17

[Java5新特性]自动装箱/拆箱的相关文章

JDK5.0新特性-自动装箱/拆箱

lJDK5.0的语法允许开发人员把一个基本数据类型直接赋给对应的包装类变量, 或者赋给 Object 类型的变量,这个过程称之为自动装箱. l自动拆箱与自动装箱与之相反,即把包装类对象直接赋给一个对应的基本类型变量. l典型应用: List list = new ArrayList(); list.add(1); int j = (Integer)list.get(0); package cn.itcast.autobox; import java.util.ArrayList; import

java基础1.5版后新特性 自动装箱拆箱 Date SimpleDateFormat Calendar.getInstance()获得一个日历对象 抽象不要生成对象 get set add System.arrayCopy()用于集合等的扩容

8种基本数据类型的8种包装类 byte Byte short Short int Integer long Long float Float double Double char Character boolean Boolean Integer a=127; Integer b=127;//虚拟机自动装箱时进行了特殊处理,-127~128以下的自动取有过的 System.out.println(a==b);结果为true 如果是Integer a=128; Integer b=128; Sys

java自动装箱拆箱总结

对于java1.5引入的自动装箱拆箱,之前只是知道一点点,最近在看一篇博客时发现自己对自动装箱拆箱这个特性了解的太少了,所以今天研究了下这个特性.以下是结合测试代码进行的总结. 测试代码: int a = 1; Integer b = 1; Integer c = 1; Integer d = 2; Integer e = 3; Integer f = 128; Integer g = 128; Long h = 3L; Double m = 4.0; Double n = 4.0; Float

基本类型包装类、自动装箱拆箱

基本类型包装类 public class Demo03 { public static void main(String[] args) { //字符串转基本数据类型 String str="12"; int strint=Integer.parseInt(str); System.out.println(strint+1);  //13 String s2="2.3"; double dou=Double.parseDouble(s2); System.out.p

(14)jdk1.5开始的一些新特性:静态导入,增强for循环,可变参数,自动装箱/拆箱,枚举类型

Jdk1.5新特性之静态导入 jdk1.5新特性值静态导入 静态导入的作用:简化缩写 静态导入的作用:可以作用一个类的所有静态成员. 静态导入的格式:import static 包名.类名.静态的成员 import static java.util.Collections.sort; //静态导入指定的某个静态成员方法 import static java.util.Collections.*;  导入所有的静态成员 除了可以导入静态的成员方法,也可以静态的导入成员变量,比如System.out

黑马程序员——【Java高新技术】——JDK1.5新特性:静态导入、可变参数、增强型for循环、自动装箱拆箱、枚举

一.静态导入 1.import和import static区别: (1)import 是导入一个类或某个包中所有的类. (2)import static是导入一个类中的某个静态方法或所有的静态方法. 注:在调用静态导入的类的静态方法时,可以不用再写类名.如Arrays.sort(int[])可以直接写sort(int[]); 2.静态导入的写法: (1)import static java.util.Arrays.*;   表示导入Arrays类中的所有静态成员. (2)import stati

Java自动装箱拆箱

一.装箱.拆箱定义 如果一个int型量被传递到需要一个Integer对象的地方,那么,编译器将在幕后插入一个对Integer构造方法的调用,这就叫做自动装箱.而如果一个Integer对象被放到需要int型量的地方,则编译器将幕后插入一个队intValue方法的调用,这就叫做自动拆箱. public static void main(String[] args) { // 装箱 Integer i1 = Integer.valueOf(1); // 自动装箱 Integer i2 = 1;// 默

Java的==和equals()以及自动装箱拆箱

抛一个问题 大家先看下面的代码,先不要看答案自己做一下: public class AutoboxingTest { public static void main(String[] args) { Integer a = 1; Integer b = 2; Integer c = 3; Integer d = 3; Integer e = 321; Integer f = 321; Long g = 3L; System.out.println(c == d); System.out.prin

自动装箱拆箱

在需要的情况下,基本类型与包装类型可以通用.有些时候我们必须使用引用数据类型时,可以传入基本数据类型.基本类型可以使用运算符直接进行计算,但是引用类型不可以.而基本类型包装类作为引用类型的一种却可以计算,原因在于,Java”偷偷地”自动地进行了对象向基本数据类型的转换. 相对应的,引用数据类型变量的值必须是new出来的内存空间地址值,而我们可以将一个基本类型的值赋值给一个基本类型包装类的引用.原因同样在于Java又”偷偷地”自动地进行了基本数据类型向对象的转换. 自动拆箱:对象转成基本数值 自动