How != and == Operators Work on Integers in Java

How != and == operators work on Integers in Java?

Integers are cached for values between -128 and 127 so Integer i = 127 will always return the same reference. Integer j = 128 will not necessarily do so. You will then need to use equals to test for equality of the underlying int.

This is part of the Java Language Specification:

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.

But 2 calls to Integer j = 128 might return the same reference (not guaranteed):

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.

do = and = relational operators work with Integer objects

Yes, but note that Integer are objects, not primitive int. Usage of >, <, >= and <= operators are not meant for objects, but for primitives, so when using any of these, the Integer is autoboxed to int. While when using == in objects you are comparing their references. Use equals instead to compare them.

Still, note that Integer class has an cache that store Integer references from -128 to 127. This means that if you do this:

Integer i1 = 127;
Integer i2 = 127;
System.out.println(i1 == i2);

Will print true.

Java: Integer equals vs. ==

The JVM is caching Integer values. Hence the comparison with == only works for numbers between -128 and 127.

Refer: #Immutable_Objects_.2F_Wrapper_Class_Caching

Why equal operator works for Integer value until 128 number?

Check out the source code of Integer . You can see the caching of values there.

The caching happens only if you use Integer.valueOf(int), not if you use new Integer(int). The autoboxing used by you uses Integer.valueOf.

According to the JLS, you can always count on the fact that for values between -128 and 127, you get the identical Integer objects after autoboxing, and on some implementations you might get identical objects even for higher values.

Actually in Java 7 (and I think in newer versions of Java 6), the implementation of the IntegerCache class has changed, and the upper bound is no longer hardcoded, but it is configurable via the property "java.lang.Integer.IntegerCache.high", so if you run your program with the VM parameter -Djava.lang.Integer.IntegerCache.high=1000, you get "Same values" for all values.

But the JLS still guarantees it only until 127:

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 characters and shorts, as well as integers and longs in the range of -32K - +32K.

how does Operators such as NOT(!), AND(&&) etc work in java?

if you make some System outs you will figure out:

char ch = 'l';
System.out.print(2 != 3);
--true, they are not equal
System.out.print('q' != 'q');
-- false, they are equals
System.out.print(ch != 'q');
-- true, they are not equals

it means, they != checks if they are exactly the same (be careful in this case is used for primitive types, such as int, char, bool, etc. this operator work differently in objects, such as String)

Integer == int allowed in java

Yes, when comparing int using == arguments will be unboxed if necessary.

Relevant section from the Java Language Specification:

15.21.1 Numerical Equality Operators == and !=

If the operands of an equality operator are both of numeric type, or one is of numeric type and the other is convertible (§5.1.8) to numeric type, binary numeric promotion is performed on the operands (§5.6.2). If the promoted type of the operands is int or long, then an integer equality test is performed; if the promoted type is float or double, then a floating-point equality test is performed.

Note that binary numeric promotion performs value set conversion (§5.1.13) and unboxing conversion (§5.1.8). Comparison is carried out accurately on floating-point values, no matter what value sets their representing values were drawn from.

Same applies for <, <=, >, >= etc, as well as +, -, * and so on.

So,

System.out.println(Integer.valueOf(17) == 17);

prints true :-)

but you can compare two equal strings with == and sometimes get true or fals depending on how the strings were pooled...

Right, and there is actually a similar situation for Integers as well.

When boxing (transforming int to Integer) the compiler uses a cache for small values (-128 - 127) and reuses the same objects for the same values, so perhaps a bit surprising, we have the following:

System.out.println(Integer.valueOf(100) == Integer.valueOf(100)); // prints true
System.out.println(Integer.valueOf(200) == Integer.valueOf(200)); // prints false

Safety of comparison operators with Integer objects in Java

It is dangerous when the variable references null. The unboxing action will cause a NullPointerException.

The <= and >= operators are different than ==. They can only be applied to numerical primitive types (and values), so reference equality is not an issue.

What does the += operator do in Java?

The "common knowledge" of programming is that x += y is an equivalent shorthand notation of x = x + y. As long as x and y are of the same type (for example, both are ints), you may consider the two statements equivalent.

However, in Java, x += y is not identical to x = x + y in general.

If x and y are of different types, the behavior of the two statements differs due to the rules of the language. For example, let's have x == 0 (int) and y == 1.1 (double):

    int x = 0;
x += 1.1; // just fine; hidden cast, x == 1 after assignment
x = x + 1.1; // won't compile! 'cannot convert from double to int'

+= performs an implicit cast, whereas for + you need to explicitly cast the second operand, otherwise you'd get a compiler error.

Quote from Joshua Bloch's Java Puzzlers:

(...) compound assignment expressions automatically cast the result of
the computation they perform to the type of the variable on their
left-hand side. If the type of the result is identical to the type of
the variable, the cast has no effect. If, however, the type of the
result is wider than that of the variable, the compound
assignment operator performs a silent narrowing primitive
conversion [JLS 5.1.3].



Related Topics



Leave a reply



Submit