一、装箱、拆箱定义


  如果一个int型量被传递到需要一个Integer对象的地方,那么,编译器将在幕后插入一个对Integer构造方法的调用,这就叫做自动装箱。而如果一个Integer对象被放到需要int型量的地方,则编译器将幕后插入一个队intValue方法的调用,这就叫做自动拆箱。

    public static void main(String[] args) {
// 装箱
Integer i1 = Integer.valueOf(1);
// 自动装箱
Integer i2 = 1;// 默认执行valueOf(1);
System.out.println(i1 == i2);// true // 自动拆箱
int i3 = i1.intValue();
int i4 = i2.intValue();
System.out.println(i3 == i4);// true // 超出Integer的缓存范围,不从私有静态内部类IntegerCache的数组cache中获得,通过new返回新对象
Integer i5 = 128;
Integer i6 = -129;
Integer i5_1 = 128;
Integer i6_1 = -129;
System.out.println(i5 == i5_1);// false
System.out.println(i6 == i6_1);// false
}

  所以说,对于-127~127之间的值,Integer对象中存在一个IntegerCache的私有静态内部类,这个内部类有一个Integer类型的静态常量数组,在这个内部类中通过静态方法块,初始化了这个静态常量数组。默认这个数组保存[-127,128)之间的Integer对象。源码如下:

     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) {
try {
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);
} catch( NumberFormatException nfe) {
// If the property cannot be parsed into an int, ignore it.
}
}
high = h; cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++); // range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127;
} private IntegerCache() {}
}

  通过下面的源码可以知道,为什么Integer i = 128;与Integer y = 128;,通过==比较的结果为false。如果要赋值的int变量在范围内,则返回数组中的对象给Integer,如果不在,则通过带参构造方法,new一个新的Integer对象。

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

二、其它包装类型


  The Java Language Specification, 3rd Edition 写道:

    为了节省内存,对于下列包装对象的两个实例,当它们的基本值相同时,他们总是==:

  • Boolean :全部缓存
  • Byte :全部缓存
  • Character : <=127缓存
  • Short : (-128,127)缓存
  • Long : (-128,127)缓存
  • Float : (没有缓存)
  • Double : (没有缓存)

其中Character的缓存源码:

   private static class CharacterCache {
private CharacterCache(){} static final Character cache[] = new Character[127 + 1]; static {
for (int i = 0; i < cache.length; i++)
cache[i] = new Character((char)i);
}
}

其中Float没有缓存,直接返回源码:

   public static Float valueOf(String s) throws NumberFormatException {
return new Float(parseFloat(s));
}

三、用处


  除了包装类提供了额外的方法外,当使用集合框架时,泛型为Object类型,所以如果声明为List<int> list...,则这样是不行的,必须声明为List<Integer> list...。

四、存储的位置


  因为是对象,所以存储在堆中。

Java自动装箱拆箱的更多相关文章

  1. java自动装箱拆箱总结

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

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

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

  3. Java 自动装箱/拆箱

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

  4. 深入理解Java自动装箱拆箱机制

    1.自动装箱与拆箱的定义 装箱就是自动将基本数据类型转换为包装器类型(int-->Integer): 拆箱就是自动将包装器类型转换为基本数据类型(Integer-->int). Java中 ...

  5. 那些年一起踩过的坑 — java 自动装箱拆箱问题

    坑在哪里?   我们都知道Java的八种基本数据类型:int, short, long, double, byte, char, float, boolean   分别有各自对应的包装类型:Integ ...

  6. Java 的自动装箱拆箱

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

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

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

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

  9. Java的自动装箱/拆箱

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

随机推荐

  1. lintcode:线段树的修改

    线段树的修改 对于一棵 最大线段树, 每个节点包含一个额外的 max 属性,用于存储该节点所代表区间的最大值. 设计一个 modify 的方法,接受三个参数 root. index 和 value.该 ...

  2. online judge 提交代码应该注意的事项

    首先,eclipse工程上出现红色的惊叹号,这个时候一般是工程的参考library或者build path的jar文件或者库文件缺失,可以右键工程,打开properties,点击 java build ...

  3. Android ActionBar详解

    Android ActionBar详解 分类: Android2014-04-30 15:23 1094人阅读 评论(0) 收藏 举报 androidActionBar   目录(?)[+]   第4 ...

  4. servlet中中文乱码问题

    在web项目中经常回碰到中文乱码的问题,特此整理一下,有不足的地方,希望大家纠正. 1从前台往后台传数据,.以get方式发送请求,发送的参数不乱,但是后台接收到参数乱码 在Tomcat的server. ...

  5. tcp抓包 Wireshark 使用

    fidder主要是针对http(s)协议进行抓包分析的,所以类似wireshark/tcpdump这种工作在tcp/ip层上的抓包工具不太一样,这种工具一般在chrome/firefox的开发者工具下 ...

  6. iOS开发多线程--技术方案

    pthread 实现多线程操作 代码实现: void * run(void *param) {    for (NSInteger i = 0; i < 1000; i++) {         ...

  7. iOS开发--iOS及Mac开源项目和学习资料

    文/零距离仰望星空(简书作者)原文链接:http://www.jianshu.com/p/f6cdbc8192ba著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”. 原文出处:codecl ...

  8. 272. Closest Binary Search Tree Value II

    题目: Given a non-empty binary search tree and a target value, find k values in the BST that are close ...

  9. Ubuntu 13.10 中文字体设置

    据我查到的资料,在默认设置下,Ubuntu 13.10 中文使用的是文泉驿正黑.我总觉得它的效果有些发虚,模糊,不满意. (貌似是Ubuntu从13.04开始取消了默认的微米黑,回退为之前的正黑.这我 ...

  10. Node 实现 AES 加密,结果输出为“byte”。

    Node 实现 AES 加密,结果输出为"byte". 最近做个需求,对接一个平台的接口,该平台采用 AES (Advanced Encryption Standard)加密算法, ...