黑马程序员技术交流社区

标题: 张孝祥老师Java高新视频学习心得之装箱拆箱 [打印本页]

作者: fantacyleo    时间: 2014-7-24 12:11
标题: 张孝祥老师Java高新视频学习心得之装箱拆箱
本帖最后由 fantacyleo 于 2015-4-16 11:50 编辑

【审核老师您好,我是申请安卓66期的李灏。因为没有做实名认证,在此表明一下我的身份】

已看完老毕的基础视频,这两天正在攻坚张老师的高新视频。还没看高新时就目睹论坛上每天大量的帖子反映高新视频难,于是决定把学习过程中的心得体会拿出来跟大家分享,欢迎大家关注。
前两篇心得不涉及论坛上热门的反射、代理、泛型,而是J2SE 5.0引入的两个语法特性:自动装箱/拆箱和可变参数,因为这两个语法特性是前24个视频中唯一让我按暂停键去查资料的知识点。本篇先说说自动装箱/拆箱,下一篇说可变参数。

对于自动拆箱/装箱,我觉得要掌握三点:
1. 概念
基本类型 boolean byte charshort int long float double null
引用类型 Boolean Byte Character Short Integer Long Float Double NullType

自动拆箱/装箱就是指由Java编译器自动完成上述前8种基本类型与其相对应的引用类型之间的【互相】转换,以及null-->引用类型的【单向】转换[1]。其中常见的是前八种,比如:
  1. // 自动装箱
  2. Integer i = 3;
  3. ArrayList<Integer> al = new ArrayList<Integer>();
  4. al.add(4);
  5. // 自动拆箱
  6. Integer j = new Integer(4);
  7. int k = j;
  8. System.out.print(3 + j);
复制代码

至于第9种null-->NullType的转换,是出于三目运算符? :赋值的语法需要[2],没必要深究。另外,不存在NullType-->null的拆箱转换,对null类型拆箱将抛出空指针异常(NullPointerException)

2. 享元设计模式
对于:

其装箱后的对象将被缓存起来,如果程序运行过程中再遇到相同的值要装箱为对象,则不再创建新对象,而是直接指向已缓存的对象,这就是享元设计模式。例如:
  1. Character c1 = 'a';
  2. Character c2 = 'a';
  3. System.out.println(c1 == c2); // true

  4. Character c3 = '\u107f';
  5. Character c4 = '\u107f';
  6. System.out.println(c3 == c4); // false
复制代码


要特别注意的是,享元特性【仅针对自动装箱】的情形,如果一个对象不是自动装箱生成的,就不具备享元特性,所以:
  1. Character c1 = 'a';
  2. Character c2 = new Character('a');
  3. System.out.println(c1 == c2); // false
复制代码


3. 自动拆箱/装箱的局限性,或者说它失效的情形:
  1. Integer i = 'a'; // 编译错误!!!
  2. ArrayList<Integer> al = new ArrayList<Integer>();
  3. al.add('a'); //  编译错误!!!
  4. short s = new Integer(1); // 编译错误!!!
  5. short s1 = 1; // 正确
复制代码

自动拆箱/装箱是不能和类型向上转换/向下转换共存的。也就是说,一条赋值语句中,执行了自动拆箱/装箱,就不会再进行类型向上转换/向下转换;执行了类型向上转换/向下转换,就不会再进行自动拆箱/装箱。
说到底,这个局限性来源于Java编译器进行赋值类型转换的规则(类型转换有一些特殊规则,参见我的另一篇帖子。):
Java编译器要求赋值语句=两边的类型必须相同,如果不同,则尝试进行如下【之一】的转换[3]:

注意关键词:之一。因此,想类型提升后再装箱,比如Integer i = 'a'; 是办不到的。只能拆成两步: int i = 'a'; Integer i1 = i; 搞清楚这个局限性非常重要,因为它可以帮助你避免可变参数函数重载时可能出现的错误,我将在下一篇说到这个问题。

[1] http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.7
[2] http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.25
[3] http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.2

作者: 李章敏    时间: 2014-7-25 13:30
总结的不错                                                                                    
作者: 为爱编程    时间: 2014-7-26 15:13
哥们 感觉你的基础好扎实啊。怎么现在还没面试吗?
作者: 咖啡苏克    时间: 2014-7-26 17:38
恩,总结的不错,谢谢分享!
作者: justin1258    时间: 2014-8-7 09:53
学习了..
作者: 轩辕苍穹    时间: 2014-8-7 10:15
谢谢楼主的分享!
作者: 大成哥    时间: 2014-8-7 10:16
总结的很好~!
作者: Hey丶小黑    时间: 2014-8-7 11:05
可以可以 ,挺好的。
作者: jeromechen    时间: 2014-8-7 11:21
总结的不错,楼主很细心学习啊,赞一个
作者: storer    时间: 2015-3-31 18:59
还好啊,只是还没有看到这里来的。
作者: dxf578939729    时间: 2015-3-31 21:31
总结的太好了!
作者: 山里孩子    时间: 2015-3-31 22:57
哇.这总结 .留个印




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2