Java JDK之小心使用boxing

自动装箱与拆箱的功能事实上是编译器来帮您的忙,编译器在编译时期依您所编写的语法,决定是否进行装箱或拆箱动作。例如:Integer i = 100;

相当于编译器自动为您作以下的语法编译:Integer i = new Integer(100);

所以自动装箱与拆箱的功能是所谓的“编译器蜜糖”(Compiler Sugar),虽然使用这个功能很方便,但在程序运行阶段您得了解Java的语义。例如下面的程序是可以通过编译的:

Integer i = null;

int j = i;

这样的语法在编译时期是合法的,但是在运行时期会有错误,因为这种写法相当于:

Integer i = null;

int j = i.intValue();

null表示i没有参考至任何的对象实体,它可以合法地指定给对象参考名称。由于实际上i并没有参考至任何的对象,所以也就不可能操作intValue()方法,这样上面的写法在运行时会出现NullPointerException错误。

自动装箱、拆箱的功能提供了方便性,但隐藏了一些细节,所以必须小心。再来看范例4.6,您认为结果是什么呢?

范例4.6 AutoBoxDemo2.java

public class AutoBoxDemo2 {
    public static void main(String[] args) {
      Integer i1 = 100;
      Integer i2 = 100;
      if (i1 == i2)
        .out.println("i1 == i2");
      else
        .out.println("i1 != i2");
    }
}

从自动装箱与拆箱的机制来看,可能会觉得结果是显示i1 == i2,您是对的。那么范例4.7的这个程序,您觉得结果是什么?

范例4.7 AutoBoxDemo3.java

public class AutoBoxDemo3 {
    public static void main(String[] args) {
      Integer i1 = 200;
      Integer i2 = 200;
      if (i1 == i2)
        .out.println("i1 == i2");
      else
        .out.println("i1 != i2");
    }
}

结果是显示i1 != i2,这有些令人惊讶,两个范例语法完全一样,只不过改个数值而已,结果却相反。

其实这与==运算符的比较有关,在第3章中介绍过==是用来比较两个基本数据类型的变量值是否相等,事实上==也用于判断两个对象引用名称是否参考至同一个对象。

在自动装箱时对于值从–128到127之间的值,它们被装箱为Integer对象后,会存在内存中被重用,所以范例4.6中使用==进行比较时,i1 与 i2实际上参考至同一个对象。如果超过了从–128到127之间的值,被装箱后的Integer对象并不会被重用,即相当于每次装箱时都新建一个 Integer对象,所以范例4.7使用==进行比较时,i1与i2参考的是不同的对象。

所以不要过分依赖自动装箱与拆箱,您还是必须知道基本数据类型与对象的差异。范例4.7最好还是依正规的方式来写,而不是依赖编译器蜜糖(Compiler Sugar)。例如范例4.7必须改写为范例4.8才是正确的。

范例4.8 AutoBoxDemo4.java

public class AutoBoxDemo4 {
    public static void main(String[] args) {
      Integer i1 = 200;
      Integer i2 = 200;
      if (i1.equals(i2))
        .out.println("i1 == i2");
      else
        .out.println("i1 != i2");
    }
}

结果这次是显示i1 == i2。使用这样的写法,相信也会比较放心一些,对于这些方便但隐藏细节的功能到底要不要用呢?基本上只有一个原则:如果您不确定就不要用。

建议新手不要使用自动装箱、拆箱的语法,在这里说明这个功能是为了要完整性介绍Java SE 6的特性,新手入门的话,最好在对对象有较深入了解之后,再来使用这个功能。

时间: 2024-10-31 15:07:42

Java JDK之小心使用boxing的相关文章

jdk-关于java JDK API的问题

问题描述 关于java JDK API的问题 关于java,JDK API 6.0中文版中那些资料怎么看,主要是注意哪些部分的内容? 解决方案 新手写程序,最好找教材去学,而不是看什么api,因为你什么都不会,你应该学基础. 好比学英语,你不应该一上来被英文字典.而api其实就相当于字典. 解决方案二: 新手写程序,最好找教材去学,而不是看什么api,因为你什么都不会,你应该学基础. 好比学英语,你不应该一上来背英文字典.而api其实就相当于字典. 解决方案三: 另外还有一点,就是如果你英文不好

JAVA JDK和Tomcat环境变量配置

CLASSPATH是什么?它的作用是什么? 它是javac编译器的一个环境变量.它的作用与import.package关键字有关.当你写下improt java.util.*时,编译器面对import关键字时,就知道你要引入java.util这个package中的类:但是编译器如何知道你把这个 package放在哪里了呢?所以你首先得告诉编译器这个package的所在位置:如何告诉它呢?就是设置CLASSPATH啦 :) 如果java.util这个package在c:/jdk/ 目录下,你得把c

eclipse-在 android java.awt 中使用 java jdk

问题描述 在 android java.awt 中使用 java jdk 我在 android 程序中使用java.awt.polygon 类.在Java构建路径中添加了 Jave JRE System library jdk 1.7 但是在使用下面这段代码时 java.awt.Polygon polyGon = new Polygon(); 获得错误NoClassDefFoundError 如何在android中使用java类? 解决方案 java awt包只使用了2个类 一个是java.aw

每日 Ubuntu 小技巧 - 在 Ubuntu 中手动安装 Oracle Java JDK 8

这篇简短的教程将会演示如何在 Ubuntu 系统中安装 Oracle 公司最新发布的 Java JDK 8.这里使用的方法是教你如何从下载页面下载安装包,然后不使用外部的 PPA 或者第三方源代码在 Ubuntu 中安装. 这种方法不需要依赖于第三方的源仓库.你只需要从 Oracle 的官方下载页直接下载,然后安装就行. JDK 8 是一个重要的发行版本,也加入了最新的叫做 Lambda 表达式的新语言功能,此功能可以"把函数用作方法参数,或者代码块当作日期数据使用". 这一个版本也发

ubuntu 14.04/CentOS 6.5中安装JAVA JDK

1.CentOS 安装JAVA JDK 方法一:直接用rpm安装 到官网去下载 http://www.oracle.com/technetwork/java/javase/downloads/index.html 然后选择RPM,下载 .我的是64位的所以选择 jdk-8u5-linux-x64.rpm #绕过验证直接下载 wget --no-check-certificate --no-cookies --header "Cookie: oraclelicense=accept-secureb

android sdk , java jdk

问题描述 为什么要先安装Java jdk 然后再安装android 的sdk ? android 会调用 jdk中的基础类吗? 解决方案 你开发的时候 因为用到eclipse等工具 是需要的,而你的android本身是不需要的 只需要android sdk,跑程序其实也只需要android的.解决方案二:android的虚拟机的这个开发环境,还有eclipse需要jdk,jvm的支持,应该编译的时候还是需要jdk的,android 的sdk里面提供了一些开发时候实用的软件adb,ddms等,还有

bat批处理设置Java JDK系统环境变量文件

原文:bat批处理设置Java JDK系统环境变量文件 自己修改第3行的Java安装目录就可以设置JAVA_HOME, classPath,追加到PATH的最前面 JAVA_HOME=C:\Program Files\Java\jdk1.6.0_10 classPath=%JAVA_HOME%\lib\tools.jar;%JAVA_HOME%\lib\dt.jar;. PATH=%JAVA_HOME%\bin;............     追加到PATH的最前面(解决最后该不该有分号的问题

java JDK环境变量设置

1.右键"我的电脑"图标,在弹出菜单中依次选择"属性"-"高级"-"环境变量". 2.在"环境变量"的"系统变量"选项新建系统变量(如果该变量已有,就修改该变量): JAVA_HOME,值为:C:\Program Files\Java\jdk1.7.0(填写你的JDK路径即可). 同样方法再建一个系统变量(如果该变量已有,就修改该变量): CLASSPATH,值为:;%JAVA_HOME

java JDK 环境变量

问题描述 重装了win7系统,安装了jdk,测试java,javac,java -version这三个命令,javac居然无法识别:'javac' is not recognized as an internal or external command,operable program or batch file.翻来覆去检查了环境变量的配置,就是看不出有什么问题:JAVA_HOME=C:Program FilesJavajdk1.6.0_01CLASSPATH=.;%JAVA_HOME%lib