Search code examples
javaobjectoperatorsprimitive

In Java, do operators perform identically on primitive types and primitive wrapper classes?


As we all know, primitives in java have mathematical and logical operators you can use on them. My question is does the same operational logic apply to their cousins, the primitive wrapper class.

Integer a = new Integer(2);
Integer b = new Integer(2);

Integer c = a * b;  //Does c.integerValue() returns 4?
boolean d = a == b; //Is d true? 
Integer e = a | c;  //Does e.integerValue() return 6?
Integer f = c % a;  //Does f.integerValue() return 0?
a++;                //Does a.integerValue() return 3?

Will all operators perform identically on primitive types and primitive wrapper classes? If not, what subset of operators work on both primitives and their Object wrappers?


Solution

  • Equality operators (== and !=) are not reliable when working with wrapper classes.

    First, generally they compare object references, not object values. For example:

    Integer a = new Integer(24);
    Integer b = new Integer(24);
    System.out.println(a == b); // Prints false
    System.out.println(a != b); // Prints true
    

    Second, how the wrapper class is created matters, for example:

    Integer a = 24;
    Integer b = 24;
    System.out.println(a == b); // Prints true
    System.out.println(a != b); // Prints false
    

    In this case, when unboxed, Integer uses Integer.valueOf that in turn uses a cache (IntegerCache) for numbers between -128 and 127. That implementation is responsible for this weird behavior.

    Actually, the implementation of the IntegerCache class allows the upper bound to be configurable via the property java.lang.Integer.IntegerCache.high when you run your program.

    This applies to Long also.

    Lesson learned, you better use the equals() method with wrappers.

    The rest of the operators should work because the value in the object is autoboxed before the operator is applied.