JDK1.5的升级引入了装箱和拆箱概念,简单说就是为了简化书写。

  JDK1.5之前,创建Integer对象是需要这么写的  Integer i = new Integer("3");

  JDK1.5之后,有了自动装箱,创建Integer对象时,我们可以这样写  Integer i = 5;

 int num = 3;
num = num + 4;
//这样写在JDK1.5中是没有问题的
Integer x = 3;
x = x + 4;

  这样以来Integer就拥有了和 int 基本类型一样的能力。表面看起来对象变的可以直接进行运算,这对编程来说方便了很多。

装箱:

  由 Integer x = new Integer(3);   简化成:Integer i = 3; 可以理解为java自动帮我们做了 x = new Integer(3)的操作。

拆箱:

  x = x + 4; 对象是不能直接用来进行运算的,所以java会自动的做拆箱的操作,把(x+4)中的 x 自动拆箱(也就是调用Integer的intValue()方法,把x转换为int类型进行运算),当运算完成之后会把运算结果再次使用装箱赋值给 x 。【整个表达式先拆箱运算完成之后再装箱】

Integer的特殊之处

 Integer a = new Integer(127);
Integer b = new Integer(127);
System.out.println(a==b);//false
System.out.println(a.equals(b));//true Integer c = 127;//JDK1.5以后,自动装箱如果装箱的是一个字节那么该数据会被共享 不会重新开辟空间
Integer d = 127;
System.out.println(c==d);//true
System.out.println(c.equals(d));//true

  通过测试上面代码的测试结果看出,JDK1.5以后Integer自动装箱的数据如果是一个字节,那么该数据会被共享,不会重新开辟新的空间。

  这就与我们上面说的装箱拆箱操作相矛盾了,如果Integer x = 3  真的代替了  Integer x = new Integer(3); 这里已经使用了new,怎么可能会不开辟新的空间呢?

  如果不开辟空间的话,那么共享数据总要存在于一块共享空间之内,难道会像字符串那样维护了一个常量池?

     /**
* Cache to support the object identity semantics of autoboxing for values between
* -128 and 127 (inclusive) as required by JLS.
*
* The cache is initialized on first usage. The size of the cache
* may be controlled by the -XX:AutoBoxCacheMax=<size> option.
* During VM initialization, java.lang.Integer.IntegerCache.high property
* may be set and saved in the private system properties in the
* sun.misc.VM class.
*/ 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() {}
}

  通过查找源码发现,原来Integer类内部维护了一个静态内部类,这是JDK1.5中,为 Integer 的操作引入了一个新的特性,用来节省内存和提高性能。整型对象在内部实现中通过使用相同的对象引用实现了缓存和重用。

  Javadoc 详细的说明这个类是用来实现缓存支持,并支持 -128 到 127 之间的自动装箱过程。最大值 127 可以通过 JVM 的启动参数 -XX:AutoBoxCacheMax=size 修改。 缓存通过一个 for 循环实现。从小到大的创建尽可能多的整数并存储在一个名为 cache 的整数数组中。这个缓存会在 Integer 类第一次被使用的时候被初始化出来。以后,就可以使用缓存中包含的实例对象,而不是创建一个新的实例(在自动装箱的情况下)。

  通过查看Integer的构造方法发现,没有一个构造方法会从IntegerCache中取值,很显然自动装箱的操作并不是通过new Integer()来完成的。应该是通过其他的方法!

     /**
* Returns an {@code Integer} instance representing the specified
* {@code int} value. If a new {@code Integer} instance is not
* required, this method should generally be used in preference to
* the constructor {@link #Integer(int)}, as this method is likely
* to yield significantly better space and time performance by
* caching frequently requested values.
*
* This method will always cache values in the range -128 to 127,
* inclusive, and may cache other values outside of this range.
*
* @param i an {@code int} value.
* @return an {@code Integer} instance representing {@code i}.
* @since 1.5
*/
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);
}

  通过查看源码发现valueOf(int i)【只有这一个方法,其他的重载方法未操作IntegerCache】中出现了对IntegerCache的操作。看源码我们了解到如果传入的-128<i<127 就会从IntegerCache的cache数组中取出共享数据,如果不在这个范围之内则使用new Integer(i)。

  由此也就彻底明白了装箱拆箱的内幕!

总结:

  > 装箱使用的是valueOf(int i)

  > 拆箱使用的是intValue();

其实这种缓存行为不仅适用于Integer对象,针对所有整数类型的类都有类似的缓存机制。

有 ByteCache 用于缓存 Byte 对象

有 ShortCache 用于缓存 Short 对象

有 LongCache 用于缓存 Long 对象

有 CharacterCache 用于缓存 Character 对象

Byte、Short、Long有固定范围:-128~127,对于 Character范围是:0~127。

除了Integer可以通过参数改变范围外,其他对象都不可以。

理解JDK1.5的自动装箱拆箱的更多相关文章

  1. Java 的自动装箱拆箱

    Java 是面向对象的语言,其基本数据类型也就有了相对应的类,称为包装类.以下是基本数据类型对应的包装类: 基本数据类型 包装类 byte(1字节) Byte short(2字节) Short int ...

  2. JAVA自动装箱拆箱与常量池

    java 自动装箱与拆箱 这个是jdk1.5以后才引入的新的内容,作为秉承发表是最好的记忆,毅然决定还是用一篇博客来代替我的记忆: java语言规范中说道:在许多情况下包装与解包装是由编译器自行完成的 ...

  3. 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 ...

  4. JDK5.0新特性(静态导入、自动装箱/拆箱、增强for循环、可变参数、枚举、泛形)

    JDK5中新增了很多新的java特性,利用这些新语法可以帮助开发人员编写出更加高效.清晰,安全的代码. 这些新特性主要有:1.静态导入2.自动装箱/拆箱3.增强for循环4.可变参数5.枚举6.泛型7 ...

  5. Java的自动装箱/拆箱

    概述 自JDK1.5开始, 引入了自动装箱/拆箱这一语法糖, 它使程序员的代码变得更加简洁, 不再需要进行显式转换.基本类型与包装类型在某些操作符的作用下, 包装类型调用valueOf()方法将原始类 ...

  6. JAVA的自动装箱拆箱

    转自:http://www.cnblogs.com/danne823/archive/2011/04/22/2025332.html 蛋呢  的空间 ??什么是自动装箱拆箱 基本数据类型的自动装箱(a ...

  7. java自动装箱拆箱总结

    对于java1.5引入的自动装箱拆箱,之前只是知道一点点,最近在看一篇博客时发现自己对自动装箱拆箱这个特性了解的太少了,所以今天研究了下这个特性.以下是结合测试代码进行的总结. 测试代码: int a ...

  8. Java八种基本数据类型的大小,以及封装类,自动装箱/拆箱的用法?

    参考:http://blog.csdn.net/mazhimazh/article/details/16799925 1. Java八种基本数据类型的大小,以及封装类,自动装箱/拆箱的用法? 原始类型 ...

  9. Java 自动装箱/拆箱

    自动装箱/拆箱大大方便了基本类型(8个基本类型)数据和它们包装类的使用 自动装箱 : 基本类型自动转为包装类(int >> Integer) 自动拆箱: 包装类自动转为基本类型(Integ ...

随机推荐

  1. 201521123050 《Java程序设计》第13周学习总结

    1. 本周学习总结 2. 书面作业 1. 网络基础 1.1 比较ping www.baidu.com与ping cec.jmu.edu.cn,分析返回结果有何不同?为什么会有这样的不同? 对比可以看出 ...

  2. es6中对象的类与继承方法

    对于对象,我一直搞不清楚到底是该如何去继承,如何去书写.在熟练es6之后,终于会尝试写出来了. 代码如下: //我们假定父类为person,子类为man class person{ construct ...

  3. git fatal: I don't handle protocol 'https'问题的解决

    问题重现 新建的仓库,再把本地的代码往上push的时候Git提示 $ fatal: I don't handle protocol 'https' 问题分析 Git是支持https的,这点毋庸置疑,所 ...

  4. ActiveMQ 入门helloworld

    1.下载安装ActiveMQ 官网下载地址:http://activemq.apache.org/download.html ActiveMQ 提供了Windows 和Linux.Unix 等几个版本 ...

  5. css常用属性2

    1  浮动和清除浮动 在上篇的第十一节--定位中说道: CSS 有三种基本的定位机制:普通流.浮动和绝对定位. 普通流和绝对定位已经说完,接下来就是浮动了. 什么是浮动? CSS 的 Float(浮动 ...

  6. mybatis错误——java.io.IOException: Could not find resource com/xxx/xxxMapper.xml

    在学习Mybatis的时候,参考网上的教程进行简单demo的搭建,配置的没有问题,然后出现了下面的错误! Exception in thread "main" java.lang. ...

  7. JSP入门 taglib

    自定义标签库(taglib),将原本需要写在jsp中的java代码封装起来,成为可复用的组件. taglib的写法和jsp动作(action)很相似,是由taglib前缀,冒号,标签名三者的组合体.其 ...

  8. Springmvc学习笔记(一)

    一.sprinvmvc的介绍 1.1.Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面.Spring 框架提供了构建 Web 应用程序的全 ...

  9. 【Spring】高级装配

    前言 前面讲解了bean的核心装配技术,其可应付很多中装配情况,但Spring提供了高级装配技术,以此实现更为高级的bean装配功能. 高级装配 配置profile bean 将所有不同bean定义放 ...

  10. HIT 1917 Peaceful Commission

    这道题题意就是给你n对人,一对中编号为x,x+1,给你m对矛盾,表示这两个人不能同时选. 然后就是Two-Sat的模板题了,就是根据对称性,连边,加缩点,最后拓扑排序,求出一组可行解就可以了. #in ...