scene
- When using Java Integer for arithmetic operation, it is occasionally found that the result is false under the premise that the two int values of = = comparison operator are the same. What is the reason?
explain
-
JDK5 has started to provide auto boxing and auto unboxing functions. The purpose is to facilitate the conversion between original data types and wrapper types, as well as arithmetic operations. In this way, it does not need to call Integer.intValue() or Integer.valueOf() frequently to convert types
-
Another function is that in the collection class, the generic type must be a reference type. Therefore, there is no such writing method as list < int > and can only be list < Integer > or list < Object >. Some methods that require object as a parameter will be automatically converted to Integer when passing int type, which is more convenient
-
When Integer is used for arithmetic and comparison operations, it will automatically unpack for int type calculation. However, there is a = = comparison operator supported by all objects. If Integer == Integer comparison is performed, Object.equals is actually called for comparison, not arithmetic comparison. Pay attention to this. Again, don't perform = = comparison on two types of integers. Convert one Integer to int and then compare two = = comparisons. Other comparison operators, such as > = will be unpacked for int comparison, which is correct
It is possible to compare the following two Integer types = = with each other
print("ie4 == ie5",ie4.compareTo(ie5) == 0); print("ie4.intValue() == ie5",ie4.intValue() == ie5); print("ie4+0 == ie5", (ie4+0) == ie5); print("(int)ie4 == ie5", (int)ie4 == ie5);
- As for the static buffer used if the Integer value is in the [- 128127] interval [2], a = = comparison can also be performed. But it's useless. Since you don't know its specific value for comparison, you don't need to consider this comparison. You'd better manually convert it to int for = = comparison
valueOf implementation by JDK:
public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }
- In addition to Integer type, the following package types support the corresponding original type:
Primitive type | Wrapper class |
---|---|
boolean | Boolean |
byte | Byte |
char | Character |
float | Float |
int | Integer |
long | Long |
short | Short |
double | Double |
example
- The following are various cases where Integer and int are boxed:
AutoBoxingTest
package com.example.string; import org.junit.jupiter.api.Test; public class AutoBoxingTest { public static<T> void print(String key,T t){ System.out.println(key +" : "+t); } public static<T> void add_1(Integer input){ input += 1; } public static void add_2(int input){ print("add_2",input); // Calling a generic method automatically boxing to Integer type } @Test public void testInteger(){ //Case 1. Integer can be used for arithmetic operators. When encountering arithmetic operators, it is automatically unpacked as int type Integer ie1 = Integer.valueOf(10); // Creates an immutable Integer object print("ie1",ie1); // 10 print("ie1 id",System.identityHashCode(ie1)); ie1 += 100; ie1 = ie1 +10; print("ie1",ie1); // 120 print("ie1 id",System.identityHashCode(ie1)); // Note: the object ID has changed and ie1 points to a different Integer object //Case 2: Integer is passed as a parameter value int i1 = ie1; // It can be assigned to the original variable and unpacked automatically print("i1",i1); // The 120 value did not change add_1(ie1); // Parameters that can be passed to the original variable print("ie1",ie1); // The 120 value did not change // Case 3: Integer can be passed to the method of int parameter. add_2(ie1); // 120 // Case 4: automatic boxing when int is passed to Integer parameter method add_1(i1); print("ie1",ie1); // 120 // Case 5: automatic boxing when int is assigned to Integer variable Integer ie2 = new Integer(120); print("ie2",ie2); // 120 Integer ie3 = 120; print("ie3",ie3); // 120 // Case 6: comparison operators between Integer and int are not allowed print("ie2 > ie1",(ie2 >= ie1)); //true print("ie2 == ie1",(ie2 == ie1)); // false print("ie3 == ie1",(ie3 == ie1)); // True - 128 < = ie < = 127 uses constant pool objects, so the comparison is the same Integer ie4 = 290; Integer ie5 = 290; print("ie4 == ie5",(ie4 == ie5)); // False > 127, a new object is created. print("ie4 >= ie5",(ie4 >= ie5)); // true auto unpacking is int comparison // Use compareTo to determine equality print("ie4 == ie5",ie4.compareTo(ie5) == 0); // true // In conclusion, do not use the = = symbol to compare two Integer type data // When integer and int operate, integer will automatically unpack to type int, and the result will also be type int. after comparing int with integer, integer will automatically unpack print("ie4+0 == ie5", (ie4+0) == ie5); // true print("(int)ie4 == ie5", (int)ie4 == ie5); // The true int cast is the same as the assignment of integer to int, which will unpack print("ie4.intValue() == ie5",ie4.intValue() == ie5); // true // The comparator used for non wrap types can only be = = String s1 = "1"; // Constant Storage String s2 = new String("1"); // Non constant pool //If (S1 > S1) / / if the non Wrapper type is compiled with the non = = comparison operator, an error is reported print("s1 == s2",(s1 == s2)); //false is converted to using equals() for comparison, so it is different // List<int> tt; // Compilation error } }