헉.. 응답 받는데 최소 3주나 걸린다는군요;;
dateCreated: Sun Feb 19 09:19:40 MST 2006
type: bug
status: Waiting
category: java
subcategory: specification
release: 5.0
hardware: x86
OSversion: win_xp
priority: 4
synopsis: Integer comparisons with == and != operator
description: FULL PRODUCT VERSION :
java version “1.5.0_06”
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_06-b05)
Java HotSpot(TM) Client VM (build 1.5.0_06-b05, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Windows XP
A DESCRIPTION OF THE PROBLEM :
As of JDK5, operator <, <=, >=, >, ==, != can be used when comparing two integers. For example, given i and j declared as below:
Integer i = new Integer(5);
Integer j = new Integer(5);
i < j and j > i return false, but operator == is not redefined for backward compatability, i.e., i == j return false because i and j are differerent instances.
However, operator == compare the value of two integer if one of them is primitive. For example, i == 5 return true. This is allowed because it won’t do any harm to backward compatability issue. This is all I know about == operator.
Things get complicated, however, when it comes to autoboxing. And I’ve found the following weird behavior in the current relase of JDK 5.
import java.util.Random; public class Test { public static void main(String[] args) { Integer i; Integer j; i = new Integer(5); j = new Integer(5); // Must be diffrent objects, because of new. System.out.println("Integer/Integer"); System.out.println( i == j ); i = 5; j = 5; // Must be the same, because these two numbers are seen // during compilation stage. System.out.println("Autoboxing/Autoboxing"); System.out.println( i == j ); // Must be the same, because 5 in the expression is seen // during compilation stage. System.out.println("Autoboxing/primitive"); System.out.println( i == 5 ); i = 5; j = new Integer(5); // Must be different, because of new. System.out.println("Autoboxing/Integer"); System.out.println( i == j ); i = 5; j = foo(); // Must be different, because of implicit new during autoboxing. System.out.println("Autoboxing/Integer(function call; no compiler optimization)"); System.out.println( i == j ); i = 5; j = bar(); // Must be different, because of explicit new. System.out.println("Autoboxing/Integer(function call; with compiler optimization)"); System.out.println( i == j ); } public static Integer foo() { // Purposely preventing compiler optimization Random r = new Random(); Integer result = r.nextInt(3); result += (5 - result); return result; } public static Integer bar() { // Let this number be hardwired return new Integer(5); } }
This program returns
Integer/Integer
false
Autoboxing/Autoboxing
true
Autoboxing/primitive
true
Autoboxing/Integer
false
Autoboxing/Integer(function call; no compiler optimization)
true
Autoboxing/Integer(function call; with compiler optimization)
false
As the comment, almost all result seem to be reasonable, except for the last two. On one hand, i == foo() return true. On the other hand, i == bar() return false. That’s strange because it is manifest that foo and bar return Integer(5).
This might be a bug. At the very least, I need justification.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED –
Autoboxing/Integer(function call; no compiler optimization)
false
Autoboxing/Integer(function call; with compiler optimization)
false
ACTUAL –
Autoboxing/Integer(function call; no compiler optimization)
true
Autoboxing/Integer(function call; with compiler optimization)
false
REPRODUCIBILITY :
This bug can be reproduced always.
———- BEGIN SOURCE ———-
import java.util.Random; public class Test { public static void main(String[] args) { Integer i; Integer j; i = new Integer(5); j = new Integer(5); // Must be diffrent objects, because of new. System.out.println("Integer/Integer"); System.out.println( i == j ); i = 5; j = 5; // Must be the same, because these two numbers are seen // during compilation stage. System.out.println("Autoboxing/Autoboxing"); System.out.println( i == j ); // Must be the same, because 5 in the expression is seen // during compilation stage. System.out.println("Autoboxing/primitive"); System.out.println( i == 5 ); i = 5; j = new Integer(5); // Must be different, because of new. System.out.println("Autoboxing/Integer"); System.out.println( i == j ); i = 5; j = foo(); // Must be different, because of implicit new during autoboxing. System.out.println("Autoboxing/Integer(function call; no compiler optimization)"); System.out.println( i == j ); i = 5; j = bar(); // Must be different, because of explicit new. System.out.println("Autoboxing/Integer(function call; with compiler optimization)"); System.out.println( i == j ); } public static Integer foo() { // Purposely preventing compiler optimization Random r = new Random(); Integer result = r.nextInt(3); result += (5 - result); return result; } public static Integer bar() { // Let this number be hardwired return new Integer(5); } }
———- END SOURCE ———-
workaround: N/A
Leave a Reply