primitive Long values 127 and 128

I want to compare two Long objects values using if conditions. When these values are less than 128 , the if condition works properly, but when they are greater than or equal to 128 , comparison fails.

Example:

Long num1 = 127;
Long num2 = 127;

if (num1 == num2) {
    // Works ok
}

Comparison on the code above works properly, but fails in the code below:

Long num1 = 128;
Long num2 = 128;

if (num1 == num2) {
    // Does NOT work
}

Why is there a problem in comparing Long variables with values greater than 127? If the variables data types are changed to long primitives , then the comparisons work for all cases.


Why there is problem in comparing Long variable with value greater than 127? If the data type of above variable is primitive (long) then code work for all values.

Java caches Integer objects instances from the range -128 to 127 . That said:

  • If you set to N Long variables the value 127 (cached), the same object instance will be pointed by all references. (N variables, 1 instance)
  • If you set to N Long variables the value 128 (not cached), you will have an object instance pointed by every reference. (N variables, N instances)
  • That's why this:

    Long val1 = 127L;
    Long val2 = 127L;
    
    System.out.println(val1 == val2);
    
    Long val3 = 128L;
    Long val4 = 128L;
    
    System.out.println(val3 == val4);
    

    Outputs this:

    true
    false

    For the 127L value, since both references (val1 and val2) point to the same object instance in memory (cached), it returns true .

    On the other hand, for the 128 value, since there is no instance for it cached in memory, a new one is created for any new assignments for boxed values, resulting in two different instances (pointed by val3 and val4) and returning false on the comparison between them.

    That happens solely because you are comparing two Long object references , not long primitive values, with the == operator. If it wasn't for this Cache mechanism, these comparisons would always fail, so the real problem here is comparing boxed values with == operator.

    Changing these variables to primitive long types will prevent this from happening, but in case you need to keep your code using Long objects, you can safely make these comparisons with the following approaches:

    System.out.println(val3.equals(val4));                     // true
    System.out.println(val3.longValue() == val4.longValue());  // true
    System.out.println((long)val3 == (long)val4);              // true
    

    IMO , it's always a good idea to stick with .equals() methods when dealing with Object comparisons.

    Disclaimer: Most comparisons will fail if any of these values are null (even casting to long will throw an exception), so additional checkings are needed to accomodate these scenarios.

    Reference links:

  • https://today.java.net/pub/a/today/2005/03/24/autoboxing.html
  • https://blogs.oracle.com/darcy/entry/boxing_and_caches_integer_valueof
  • http://java.dzone.com/articles/surprising-results-autoboxing

  • num1 and num2 are Long objects. You should be using equals() to compare them. == comparison might work sometimes because of the way JVM boxes primitives, but don't depend on it.

    if (num1.equals(num1))
    {
     //code
    }
    

    Java caches the primitive values from -128 to 127 . When we compare two Long objects java internally type cast it to primitive value and compare it. But above 127 the Long object will not get type caste. Java caches the output by .valueOf() method.

    This caching works for Byte, Short, Long from -128 to 127. For Integer caching works From -128 to java.lang.Integer.IntegerCache.high or 127, whichever is bigger.(We can set top level value upto which Integer values should get cached by using java.lang.Integer.IntegerCache.high).

     For example:
        If we set java.lang.Integer.IntegerCache.high=500;
        then values from -128 to 500 will get cached and 
    
        Integer a=498;
        Integer b=499;
        System.out.println(a==b)
    
        Output will be "true".
    

    Float and Double objects never gets cached.

    Character will get cache from 0 to 127

    You are comparing two objects. so == operator will check equality of object references. There are following ways to do it.

    1) type cast both objects into primitive values and compare

        (long)val3 == (long)val4
    

    2) read value of object and compare

        val3.longValue() == val4.longValue()
    

    3) Use equals() method on object comparison.

        val3.equals(val4);  
    
    链接地址: http://www.djcxy.com/p/10046.html

    上一篇: 在Python中比较性能:相等与不相等

    下一篇: 原始长值127和128