Java autoboxing rules
Asked Answered
N

4

12

I am a java novice and so confused by the following example. Is it okay to think that "==" sign will compare the values between Integers and "autoboxed" Integers from int, and compare reference address between Integers?

What about doubles and 0/0?

import edu.princeton.cs.introcs.*;

public class Autoboxing {

    public static void cmp(Integer first, Integer second) {
        if (first < second)
            StdOut.printf("%d < %d\n", first, second);
        else if (first == second)
            StdOut.printf("%d == %d\n", first, second);
        else if (first > second)
            StdOut.printf("%d > %d\n", first, second);
        else
            StdOut.printf("%d and %d are incomparable\n", first, second);
    }

    public static void main(String[] args) {
        cmp(new Integer(42), 43);
        cmp(new Integer(42), new Integer(42));
        cmp(43, 43);
        cmp(142, 142);

        Integer a0 = 1000;
        int b0 = 1000;
        Integer c0 = 1000;
        StdOut.println("a0==b0?" + (a0==b0));
        StdOut.println("a0==c0?" + (a0==c0));
        StdOut.println("b0==c0?" + (b0==c0));

        double x1 = 0.0, y1 = -0.0;
        Double a1 = x1, b1 = y1;
        StdOut.println(x1 == y1);
        StdOut.println(a1.equals(b1));

        double x2 = 0.0/0.0, y2 = 0.0/0.0;
        Double a2 = x2, b2 = y2;
        StdOut.println(x2 != y2);
        StdOut.println(!a2.equals(b2));
    }

}

The result is:

42 < 43
42 and 42 are incomparable
43 == 43
142 and 142 are incomparable
=====
a0==b0?true
a0==c0?false
b0==c0?true
=====
true
false
=====
true
false
Near answered 24/9, 2012 at 6:3 Comment(2)
Have you tried? System.out.println("eq " + (new Integer(10) == 10));Nica
answer explained here linkHighoctane
B
26

Unboxing will be happing when arithmetic operators, comparison operators appear.

eg:

Integer a = 10;
a = a+10; //1.unboxing a to int 2.calculate a+10 3.boxing 20 to Integer.
System.out.print(a > 10); //1.unboxing a to int 2. compare

But when == appear, it depends.

If boxing type appear on both side, it will compare the reference.But if base type appear on one side, and the other side is a boxing type, the boxing type will unboxing to base type.

eg:

Integer a = new Integer(129);
Integer b = new Integer(129);
System.out.println(a == b); // compare reference return false
System.out.println(a == 129); // a will unboxing and compare 129 == 129 return true

PS: In Java.lang.Integer Cache to support the object identity semantics of autoboxing for values between -128 and 127 (inclusive) as required by JLS. See source code

So:

Integer a = 127;
Integer b = 127; //cached, the same as b a==b return ture

Integer c = 129;
Integer d = 129; // not cached, c==d return false
Betook answered 24/9, 2012 at 6:36 Comment(2)
But how come does Object o1=3; Object o2=3; System.out.println(o1==o2); return true? Both sides of the == here are boxing typesDarra
This happens because of the Integer Cache. Under the hood, the compiler replaces the assignments above with Object o1=Integer.valueOf(3); and Object o2=Integer.valueOf(3);. The implementation of Integer.valueOf(int) saves certain instances of Integer for re-use. Thus, while the two objects on either side of the == operator are never unboxed, they have the same reference. More: javapapers.com/java/java-integer-cacheMarsha
T
12

Here is the Tutorial for Autoboxing and Unboxing.

You can also go through JLS#5.1.7. Boxing Conversion and JLS#5.1.8. Unboxing Conversion

0.0 / 0.0 is NaN you can not compare infinity at least in maths. I guess that is why this comparison does not work.

From JLS #4.2.3. Floating-Point Types, Formats, and Values

Positive zero and negative zero compare equal; thus the result of the expression 0.0==-0.0 is true and the result of 0.0>-0.0 is false

NaN is unordered, so:

  • The numerical comparison operators <, <=, >, and >= return false if either or both operands are NaN (§15.20.1).

  • The equality operator == returns false if either operand is NaN.

  • In particular, (x=y) will be false if x or y is NaN.

  • The inequality operator != returns true if either operand is NaN (§15.21.1).

  • In particular, x!=x is true if and only if x is NaN.

If you check Double#equals method it has two exceptions

also has the value true. However, there are two exceptions:

  • If d1 and d2 both represent Double.NaN, then the equals method returns true, even though Double.NaN==Double.NaN has the value false.

  • If d1 represents +0.0 while d2 represents -0.0, or vice versa, the equal test has the value false, even though +0.0==-0.0 has the value true.

This definition allows hash tables to operate properly.

Tolerance answered 24/9, 2012 at 6:7 Comment(2)
thanks~ so a2 and b2 both are boolean value false, therefore equal to each other?Near
a2.equals(b2) will always return true if both are NAN which is documented in the Java doc of equals method.Tolerance
P
1

== can only be used for checking if the variables are equal or not if the variables are primitive types. For object variables, == is used to compare the reference of the objects. If you want to compare the values of the objects, use .equals() method.

Phalan answered 24/9, 2012 at 6:9 Comment(0)
M
0

I would not recommend comparing boxed ints with ==, as it works only for some values.

Monosyllable answered 24/9, 2012 at 6:25 Comment(2)
I am also reading articles, it seems that for int, == compares the values between -127 - 127.Near
Yes. it's kind of a cache. Use .equals() when you have Integers and == when you have ints.Monosyllable

© 2022 - 2024 — McMap. All rights reserved.