首先,让大家看个简单的程序:
public class AutoBoxingTester {
public static void judgeEqual(Integer i, Integer j) {
if (i == j) {
System.out.println("Equal!");
} else {
System.out.println("Not Equal!");
}
}
public static void main(String[] args) {
Integer i = 100;
Integer j = 100;
judgeEqual(i, j);
Integer a = 255;
Integer b = 255;
judgeEqual(a, b);
}
}
大家会觉得程序输出结果是什么呢?两个"Equal"?或者两个"Not Equal"?
可能程序的输出结果会与大家预期的想法有点出入,程序在第一次判断中会输出"Equal",而在第二次判断中会输出"Not Equal"。为什么会这样呢?这就要从Java 1.5加入的新特性,Autoboxing与Unboxing讲起了。
int、 short、char等,是Java中的Primitive类型,也就是非对象类型,因此,Java提供了一种Wrapper Class(包装类),像是Integer、Short、Character等,用来把Primitive类型的变量包装成对象类型。在Java 1.5之前的版本,这种转换需要通过手工进行,但是做这样的转换是编程过程中是很繁琐的,所以Java 1.5借由boxing消除了这种"不合理"的需求,JVM会自动处理从Primitive类型到对象Wrapper类型的转换,反之亦然。
上面的程序是两个Wrapper对象的比较,100和255分别被box进两个不同的对象i和j,a和b中,然后两个对象以"=="来作比较,因为两个对象 是不同的实例,有着不同的内存地址,所以按道理来说,程序两次判断的输出都应该为"Not Equal"才正确。然而,为什么程序第一次判断的输出会为"Equal"呢?难道是JVM出错了吗?
非也!Java规范指出:特定的Primitive一定得被box成相同的不可变的wrapper对象。这些对象会被高速缓存重复使用,并且会被当作一般的对象使用。这些特定的Primitive包括:boolean值的true和false、所有的byte值、介于-128至127的short与int的值、以及介于\u0000与\u007F之间的任何一个char。
所以,JVM确实对i和j使用了相同的对象实例(以及内存地址),因此,"=="运算符的结果为true,在第一次判断中自然就会输出Equal了。
在编程过程中必须小心注意此种情况的出现,因为它极可能会引发一些古怪而又难以发现的Bug。
分享到:
相关推荐
2. **Autoboxing and Unboxing.txt** - 自动装箱与拆箱是Java中的一项特性,允许基本类型与对应的包装类之间无缝转换。在Hibernate中,这可能涉及到将基本类型(如int)与实体类的属性进行映射,文件可能解释了...
2. **自动装箱与拆箱(Autoboxing and Unboxing)**:自动装箱允许开发者在需要原始类型的地方使用对应的包装类,反之亦然。例如,Integer 和 int 之间的转换无需手动进行。 3. **枚举(Enums)**:Java 1.5 引入了...
3. **自动装箱/拆箱(Autoboxing and Unboxing)**: 自动装箱和拆箱使得基础类型与它们对应的包装类之间的转换变得无缝。在JDK1.5.0_12的源代码中,可以看到编译器如何处理这种转换,例如,当基本类型与包装类进行...
自动装箱与拆箱(Autoboxing and Unboxing) JDK1.5开始,基础数据类型(如int、char等)与它们对应的包装类(如Integer、Character等)之间实现了自动装箱和拆箱操作,使得在处理这些类型时更加方便。 ### 3. ...
- **自动装箱(Autoboxing)与拆箱(Unboxing)**:自动装箱是指Java编译器自动将基本数据类型转换为其对应的包装类类型的过程。例如,将`int`类型转换为`Integer`对象。相反,拆箱是指从包装类类型转换回基本数据类型的...
2. **自动装箱与拆箱(Autoboxing and Unboxing)**:在JDK 1.5之前,基本类型和其对应的包装类之间需要手动进行转换。1.5版本引入了自动装箱和拆箱,使得基本类型和包装类之间的转换变得更加简洁和自动化。 3. **...
- **自动装箱和拆箱(Autoboxing and Unboxing)**: 自动装箱指的是基本数据类型被转换为对应的包装类型,而自动拆箱则是相反过程。 - **增强的for循环(Enhanced For Loop)**: 提供了一种更简洁的方式来遍历数组或...
3. **自动装箱/拆箱(Autoboxing and Unboxing)**:Java 5.0自动处理基本类型和其对应的包装类之间的转换,大大简化了代码,减少了程序员的工作量。 4. **变量枚举(Varargs)**:变长参数(varargs)允许在方法...
自动装箱(Autoboxing)和拆箱(Unboxing)是Java中自动将基本类型与它们对应的包装类之间转换的过程。 6. **函数重载**是指在同一个类中可以有多个同名但参数列表不同的方法。方法覆盖(Overriding)是子类重新...
相信每一个Java开发人员,都曾经用过诸如Jad之类的反编译器,对Java的class 文件进行反编译,从而观察程序的结构与实现细节。如此一来,对于那些需要严格进行知识产权保护的Java应用,如何有效的保护客户的商业投资...
相信每一个Java开发人员,都曾经用过诸如Jad之类的反编译器,对Java的class 文件进行反编译,从而观察程序的结构与实现细节。如此一来,对于那些需要严格进行知识产权保护的Java应用,如何有效的保护客户的商业投资...
相信每一个Java开发人员,都曾经用过诸如Jad之类的反编译器,对Java的class 文件进行反编译,从而观察程序的结构与实现细节。如此一来,对于那些需要严格进行知识产权保护的Java应用,如何有效的保护客户的商业投资...
11. **封箱类型的非空实例断言(Nullness Annotations for Autoboxing and Unboxing)**:从Java 15开始,对封箱类型(如Integer)的自动装箱和拆箱操作添加了非空注解支持,避免了因为空指针异常导致的错误。...
14. **Analysis**:分析,软件开发过程中的阶段,用于理解需求并设计解决方案。 15. **Native Machine Instructions**:原始机器语言,计算机可以直接执行的二进制指令。 16. **Bytecode**:字节码,Java程序编译后...
3. **自动装箱/拆箱(Autoboxing and Unboxing)**:Java5自动处理基础类型与对应的包装类之间的转换,简化了代码。 4. **匿名内部类(Anonymous Inner Classes)**:在Java5中,可以更加简洁地创建实现了特定接口...
Java为了解决这个问题,从JDK 5.0开始引入了自动装箱(Autoboxing)和拆箱(Unboxing)机制,使得在整型数和Integer对象之间转换变得更加便捷。然而,这并不意味着每次都会创建新的Integer对象。在特定范围内,...
在Java编程语言中,`Integer.valueOf()`方法是一个关键的知识点,尤其对于理解自动装箱(autoboxing)和拆箱(unboxing)机制至关重要。在Java中,基本类型`int`与封装类`Integer`之间可以自动转换,这就是所谓的...