码迷,mamicode.com
首页 > 编程语言 > 详细

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

时间:2015-06-07 15:51:00      阅读:164      评论:0      收藏:0      [点我收藏+]

标签:包装类   装箱   拆箱   自动   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){

    }

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

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

标签:包装类   装箱   拆箱   自动   java   

原文地址:http://blog.csdn.net/u012483425/article/details/46400995

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!