• Java 自动装箱与拆箱


    Java为每种基本数据类型都提供了对应的对象类型。在Java SE5之前,如果要生成一个数值为7的Integer对象,代码示例:Integer i = new Integer(7);;Java SE5之后,Java提供了新的语法,简化了基本数据类型对象的使用,我们称之为自动装箱(autoboxing)与拆箱(unboxing)。之前的代码可以简化为Integer i = 7;。

    Java提供的自动装箱盒拆箱,是在编译器层实现的。编译之后的字节码仍然是如Java SE5之前的形态。如自动装箱使用对象的valueOf方法实现的,而拆箱使用对象的 xxxValue方法实现的,xxx代表对应的基本数据类型。

    自动装箱与拆箱的原理很简单,通常面试会问对象比较的问题,以考察候选人对源码的了解程度。比较典型的案例是使用==来比较对象是否相等。在实际工作中通常使用对象的equals方法,这是没有问题的。==操作是比较对象的地址是否相同,只要两个地址指向的对象不同,==操作就会返回false。

    对于基本数据类型的对象来说,由于考虑到有些对象是会经常使用到的,如果频繁的进行对象的创建和回收,会极大的影响系统效率。因此Java规范也规定需要对于经常使用的对象进行缓存。

    对于Integer类型,具体实现中使用了IntegerCache类做缓存,缓存了数值在[-128,127]之间的对象,valueOf方法对于缓存的对象会直接返回对象引用,否则会调用Integer的构造函数创建新对象。因此自动装箱对于[-128,127]之间的数,使用==操作时会返回true,其他情况是false。但有一点需要注意,如果是直接调用构造方法生成的对象,永远都是新对象,也就是说==操作都会返回false。

    类似的实现,Short、Long、Byte、Integer都是缓存了数值在[-128,127]之间的相应对象;Character对应char类型,没有负数,因此缓存了[0,127]之间的相应对象;Boolean只有两个数值,都做了缓存。

    至于Double和Float,他们没有做任何缓存。其原因可能是:

    1. 由于在某个范围内的整型数值的个数是有限的,而浮点数却不是;

    2. 很难评估哪些数是经常被使用到,或者说没有像整型数值那样的在实际使用过程中被经常用到的数值;

    基于之前的讨论,我们知道定义数值类型可以使用Integer i = new Integer(7);或者Integer i = 7;,两者在使用上主要注意:

    1. 前者不会触发自动装箱,而后者会触发自动装箱过程;

    2. 前者直接生成新对象,而后者会根据具体数值,决定是否生成新对象,还是返回缓存对象的引用;

    3. 从执行效率和资源占用上来看,后者的效果更高,推荐使用;

    另外,在实际工作中,我们还是尽量使用equals方法吧,实在是想不到什么时候会用==操作啊 (除了面试的时候:))

  • 相关阅读:
    The analysis of China's holding the Olympic Games
    ASP.NET获取客户端的操作系统、浏览器、.NET版本等信息(图)
    ASP.NET 无提示关闭窗口
    VC 使用CryptoAPI计算Hash值:MD5, SHA
    SQL Server 2005 中设置某个用户对某一个数据库有完全控制的权限
    C# 计算文件的MD5值
    VC 获取物理网卡的MAC地址
    哪些免费邮箱不在邮件内容里插广告?
    忆同学
    使用正则表达式获取连接字符串某项的值
  • 原文地址:https://www.cnblogs.com/pkufork/p/java_autoboxing.html
Copyright © 2020-2023  润新知