Java基础之包装类的自动装箱和拆箱详解

定义

在java中,数据类型可以分为两大类,即基本数据类型和引用数据类型,基本数据类型的数据不是对象,所以对于要将数据类型作为对象来使用的情况,java提供了相对应的包装类。(关于包装类的详细介绍请参看博客Java基础之常用类详解

本篇博客主要讲述包装类的自动装箱和拆行机制。

所谓装箱,就是把基本数据类型用它们相对应的引用类型包起来,使它们可以具有对象的特质,如我们可以把int类型包装成Integer类型的对象,或者把double包装秤Double,等等。

所谓拆箱,就是和装箱的方向相反,将Integer即Double这样的引用类型的对象重新简化成基本数据类型的数据。

而java JDK引入的自动装箱和拆箱就是编译器来依据我们编写的代码,决定是否进行装箱和拆箱动作。即无需使用valueOf()和intValue()等方法。(如果这方面不熟悉请参看博客Java基础之常用类详解

关于自动装箱拆箱机制的注意事项

这是本篇博客要讲述的重点

先看一个小例子:


public class WrapperText {

    public static void main(String[] args) {
        Integer a = 100;
        Integer b = 100;

        Integer c = 200;
        Integer d = 200;

        System.out.println(a == b);//1
        System.out.println(a == 100);//2

        System.out.println(c == d);//3
        System.out.println(c == 200);//4
    }

}

如果我们对于Java中自动装箱和拆箱操作了解不够深入的话,一定会这么想:自动装箱后,abcd都是Integer对象的不同引用,“==”操作符又是用来比较对象引用的,所以1和3都应输出false。而对于2和4,由于a和c都进行了自动拆箱,因此其比较是基本数据类型的比较。“==”操作符比较的使它们的值,所以2和4因该输出true。即最终结果输出:

false

true

false

true

但是正确的结果却是:

我们看到1的结果为true,3的结果为false,这是为什么呢。其实很简单,自动装箱过程其实是调用了valueOf()的方法,而valueOf()方法的源码为:

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

        static {
            // high value may be configured by property
            int h = 127;
            String integerCacheHighPropValue =
                sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
            if (integerCacheHighPropValue != null) {
                int i = parseInt(integerCacheHighPropValue);
                i = Math.max(i, 127);
                // Maximum array size is Integer.MAX_VALUE
                h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
            }
            high = h;

            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);
        }

        private IntegerCache() {}
    }

通过阅读源代码,可以发现,java内部为了节省内存,IntegerCache类中有一个数组缓存了值从-128到127的Integer对象。当我们调用Integer.valueOf(int i)的时候,如果i的值时结余-128到127之间的,会直接从这个缓存中返回一个对象,否则就new一个新的Integer对象。因此,1为true,3为false。

最后分享一道与之相关的很有意思的题目:

请提供一个对i的声明,将下面的循环转变成为一个无限循环:

while(j <= i && i <= j && i != j){

    }

相信如果仔细阅读了本篇博客,这道题一定能够很轻松的解决。

时间: 2024-10-24 13:58:04

Java基础之包装类的自动装箱和拆箱详解的相关文章

Java中自动装箱与拆箱详解

在讲装箱与拆箱之前我们要先了解一下这个问题的来源: Java中的类型分为基本类型(Primitive type)和类类型(Class type)两种: 基本类型包括byte型.char型.short型.int型.long型.float型.double型.boolean型八种.基本类型指的是直接包含值得类型,可提供语言级别的支持. 类类型包括Byte.Character.Short.Integer.Long.Float.Double.Boolean.为什么要用类类型呢?原因其实很简单,因为Java

JAVA随笔—JDK1.5的自动装箱与拆箱

今天偶然间发现项目里Integer类型的变量用“==”进行比较的,但是却一直没出现问题.所以就上网查了查,发现这里面涉及到JDK1.5的新特性. 1.Java中的数据类型,可分为两类: a.基本数据类型,也称原始数据类型.short,char,int,long,float,double,boolean,byte 用“==”进行比较. b.引用数据类型(类) 比较引用类型变量值的时候,需要调用equals()方法,当他们用“==”进行比较的时候,比较的是他们在内存中的存放地址. 2.先运行这段代码

Java基础 【自动装箱和拆箱、面试题】

JDK 1.5 (以后的版本)的新特性自动装箱和拆箱 1. 自动装箱:把基本类型转换为包装类类型 int a =10; Integer i = new Integer(a); Integer value = 10; 为什么基本类型就能直接转化为Integer ,Integer 不应该是new出来的吗 内部会自动的 new Integer(10) 自动装箱 2. 自动拆箱: 把包装类型转换为基本类型 Integer value2 = new Integer(120); int a = value2

java自动装箱与拆箱

基本数据(Primitive)类型的自动装箱(autoboxing).拆箱(unboxing)是J2SE 5.0提供的新功能,跟泛型.变长参数等一样,这也是一颗"语法糖",之前介绍jvm早期优化的时候说过,语法糖对运行期的代码没有任何影响,其目的仅仅是方便程序员使用,所有语法糖编译后都将会还原成基础语法.这次介绍的自动装箱和拆箱也不例外.看下头的例子: public class Demo { public static void main(String[] args) { Intege

《Java中的自动装箱和拆箱功能.》

1 //Java中的自动装箱和拆箱功能. 2 class AutoboxingUnboxing 3 { 4 public static void main(String[] args) 5 { 6 //直接把一个基本类型变量赋给Interger对象. 7 Integer inObj = 5; 8 Object inObj1 = 6; 9 //直接把一个boolean类型的变量赋给一个Object类型的变量. 10 Object boolObj = true; 11 //直接把Integer对象赋

Java 自动装箱和拆箱

JDK1.5之后的功能 自动装箱:指的是开发人员可以把一个基本数据类型直接赋给对应的包装类 自动拆箱:指开发人员可以把一个包装类对象直接赋给对应的基本数据类型 public static void main(String[] args) { Integer i = 1; //装箱 int j = i ; //拆箱 } public static void main(String[] args) { List list = new ArrayList(); list.add(1); int j=

Java的自动装箱和拆箱

1 public class BoxingDemo { 2 3 public static void main(String[] args) { 4 5 /** 6 * 自动装箱示例: 7 * 基本类型int是不能直接赋值给其包装类对象Integer的,但是这里这条语句可以编译通过 8 * 因为自动装箱原理隐式包含了下面2条语句: 9 * Integer temp = new Integer(1); 10 * int1 = temp; 11 * */ 12 Integer int1 = 1; 1

Java 自动装箱和拆箱那些事

1.JAVA的基本数据类型 在Java中,数据类型可以分为两大种,Primitive Type(基本类型)和Reference Type(引用类型).基本类型的数值不是对象,不能调用对象的toString().hashCode().getClass().equals()等方法.所以Java提供了针对每种基本类型的包装类型.如下: Java基本数据类型 INDEX 基本类型  大小 数值范围 默认值 包装类型 1 boolean    --- true,false false Boolean 2

跟王老师学泛型(二):Java自动装箱与拆箱

Java 自动装箱与拆箱(Autoboxing and unboxing) 主讲教师:王少华 QQ群:483773664 学习目标: 掌握Java 基本数据对应的包装类 掌握Java 自动装箱与拆箱 一.基本数据类型对应的包装类 Java为每一种基本数据类型都提供了一个包装类,而这些包装类就在java.lang包中.Java共有8个包装类.如下图所示: 包装所有数字类型类都继承自Number类,Number类是一个抽象类. 二.什么是自动装箱拆箱 基本数据类型的自动装箱(autoboxing).