Java has two integer types: primitive and object. Integer types are often used when serialization is an issue. For example in case of JPA entities you will probably want to use the Integer type. The problem with this type is that it’s confusing. It looks like a primitive but it’s NOT!
Let’s take this simple example:
Integer a = 100; Integer b = 100; if (a == b) System.out.println("Same."); else System.out.println("Different."); // The output: Same
The output for this snippet is “Same”. Seems legit, we comparing two integer values, it’s obvious that these values are the same. Now let’s take another example:
Integer a = new Integer(100); Integer b = new Integer(100); if (a == b) System.out.println("Same."); else System.out.println("Different."); // The output: Different
Wait a minute! We compare the exact same values as above, but we got a different result. The thing is that in this case we explicitly create two Integer objects. They are not the same because we talk about separate instances and the == operator in Java checks if the instances are exactly the same. Now let’s make this really ugly:
Integer a = 200; Integer b = 200; if (a == b) System.out.println("Same."); else System.out.println("Different."); // The output: Different
What the F..K? Why are the values different? Well, it turns out that it’s pure luck that the first example works. The thing is that Java caches the Integer instances from -128 to 128. So when you are not explicitly create a new Integer instance, it will return the cached instance IF IT’S IN THE CACHED RANGE. Otherwise a new Integer object is created on the fly.
In Java, the “==” is always used for object equality, it has not been overloaded for comparing unboxed values. So if you have Integer values, compare them using equals().