5

Take a look at following code:

Long minima =          -9223372036854775808L;
        Long anotherminima =   -9223372036854775808L;
        System.out.println(minima==anotherminima); //evaluates to false
        System.out.println(Long.MIN_VALUE); 
        Long another= 1L;
        Long one = 1L;
        System.out.println(another == one); //evaluates to true

I am not able to understand this behavior..? I was hoping the first eval to be true as well.. And that is what I am expecting..

frazman
  • 32,081
  • 75
  • 184
  • 269

6 Answers6

4

There is a caching technique used by the JVM for some range of autoboxing value. As specified in the spec ( http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.7 )

If the value p being boxed is true, false, a byte, or a char in the range \u0000 to \u007f, or an int or short number between -128 and 127 (inclusive), then let r1 and r2 be the results of any two boxing conversions of p. It is always the case that r1 == r2.

Ideally, boxing a given primitive value p, would always yield an identical reference. In practice, this may not be feasible using existing implementation techniques. The rules above are a pragmatic compromise. The final clause above requires that certain common values always be boxed into indistinguishable objects. The implementation may cache these, lazily or eagerly. For other values, this formulation disallows any assumptions about the identity of the boxed values on the programmer's part. This would allow (but not require) sharing of some or all of these references.

This ensures that in most common cases, the behavior will be the desired one, without imposing an undue performance penalty, especially on small devices. Less memory-limited implementations might, for example, cache all char and short values, as well as int and long values in the range of -32K to +32K.

So 1L is in this cached values and then the autoboxing give the exact same reference, but in the case of the number outside of this range (like the Long.MIN_VALUE) it isn'T cached and thus a different instance/reference is given.

In any case, when comparing object you should always use .equals()

Community
  • 1
  • 1
Jonatan Cloutier
  • 899
  • 9
  • 26
3

Just a guess here, but it could be that 1L is in the constant pool, and thus the reference equality evaluates to true (just like how sometimes, even by Strings, == will evaluate to true), while that other huge number isn't. Not sure how to check which constants are in the pool at initiation.

Edit: Java has a cache of certain constant objects (including the wrapper classes for primitives, and String). Thus, if you write

String st1 = "A";

if "A" is in the constant pool, Java won't create a new String object- it will just create a reference to the already existing one. So if you then did

String st2 = "A";
System.out.println(st1 == st2);

It would print out true.

Now, not all Integer, Long, Short, etc... are cached (there are way too many), but the lower values are. So I would assume that 1L is. That means that in your question, both another and one refer to the same object, and thus it returns true even for reference equality.

Sherz
  • 568
  • 2
  • 14
  • I definitely might be wrong, but would be interested in hearing why. – Sherz Aug 24 '14 at 05:34
  • This is definitely right, but the answer isn't very helpful if you don't already know what the "constant pool" refers to. – Chris Hayes Aug 24 '14 at 05:35
  • +1 to you for mentioning the word constant pool. That is the correct answer. I am copy-pasting a blog with the answer, with due credit. – Erran Morad Aug 24 '14 at 05:37
3

First of all you should use long instead of Long. Secondly == between Integer, Long etc will check for reference equality. You may check the 5.1.7 Boxing Conversion. Alo 1L is in the constant pool so the second case is returning true.

On a side note you should use .equals for comparing the long.

From the Oracle docs:

If the value p being boxed is true, false, a byte, or a char in the range \u0000 to \u007f, or an int or short number between -128 and 127 (inclusive), then let r1 and r2 be the results of any two boxing conversions of p. It is always the case that r1 == r2.

Ideally, boxing a given primitive value p, would always yield an identical reference. In practice, this may not be feasible using existing implementation techniques. The rules above are a pragmatic compromise. The final clause above requires that certain common values always be boxed into indistinguishable objects. [...]

This ensures that in most common cases, the behavior will be the desired one, without imposing an undue performance penalty, especially on small devices. Less memory-limited implementations might, for example, cache all char and short values, as well as int and long values in the range of -32K to +32K.

Rahul Tripathi
  • 168,305
  • 31
  • 280
  • 331
0

problem:

(minima==anotherminima)

You are comparing the memory location of the object not its values thus it returns false.

If you want to compare two long wrapper class you need to call compareTo

From jls

If the value p being boxed is true, false, a byte, or a char in the range \u0000 to \u007f, 
or an int or short number between -128 and 127 (inclusive), then let r1 and r2 be the results 
of any two boxing conversions of p. It is always the case that r1 == r2.

Now if you use -128 and 127 to initialized the Long wrapper class it will result to boxing conversion which will have the same reference.

Rod_Algonquin
  • 26,074
  • 6
  • 52
  • 63
0

Adding on to this answer, everything from -128 to 127 is cached into an instance in permanent java memory, meaning that those numbers (almost) always have reference equality, because new instances are not created for them. Outside of the cache, a new instance is created every time the number is used, so they are not equal referentially. Read more here and here

Community
  • 1
  • 1
Kyranstar
  • 1,650
  • 2
  • 14
  • 35
  • I rubbed your back :) – Erran Morad Aug 24 '14 at 05:40
  • 1
    If you have something to add to an answer, you should consider editing it, or posting a comment to that answer. – jdphenix Aug 24 '14 at 05:42
  • @jdphenix - man i removed my answer due to all the hate i am getting. Some people don't have the balls to tell why they downvote. – Erran Morad Aug 24 '14 at 05:44
  • 2
    Downvoting does not indicate an ad hominem attack on the poster. It does indicate some dissatisfaction with the content they posted. In this case - this question already has a well written answer that's been linked as a duplicate. – jdphenix Aug 24 '14 at 05:47
-2

You should use long instead of Long. Note that Long is a class and so you must use equals() to compare instances of it. On the other hand, if you use long instead, you can compare with == because these are primitives.

Code-Apprentice
  • 81,660
  • 23
  • 145
  • 268