Integer
The source code of this article is based on JDK8
Integer is also a tool class and packaging class that we often use. This article is mainly used to record study notes, mainly from the perspective of source code.
public final class Integer extends Number implements Comparable<Integer> {
// 2147483647
public static final int MIN_VALUE = 0x80000000;
// -2147483648
public static final int MAX_VALUE = 0x7fffffff;
// 获取基本类型int类型是class
public static final Class<Integer> TYPE = (Class<Integer>) Class.getPrimitiveClass("int");
}
Description: Integer.TYPE == int.class // true
- Inherit the Number class
There are only constructors and a few abstract methods in the Number class:
Construction method
public Integer(int value) {
this.value = value;
}
public Integer(String s) throws NumberFormatException {
this.value = parseInt(s, 10);
}
Autoboxing and Autounboxing
After JDK1.5, java provides the functions of automatic boxing and automatic unboxing. Let's analyze the boxing of Integer from the perspective of source code:
package com.quancheng;
public class ClassTest {
public static void main(String[] args) throws InterruptedException {
Integer num = 10;
}
}
Looking at the bytecode through javap -v ClassTest.class, we can see that autoboxing is actually what the JVM compiler does for us, calling the Integer.valueOf() method
public static void main(java.lang.String[]) throws java.lang.InterruptedException;
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=1, locals=2, args_size=1
0: bipush 10
2: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
5: astore_1
6: return
It can be seen from the analysis here that Integer a = 100 is actually equivalent to Integer a = Integer.valueOf(100); but this work is done for us by the JVM;
Automatic unboxing:
public static void main(String[] args) throws InterruptedException {
int num = new Integer(11);
}
The corresponding bytecode instruction:
public static void main(java.lang.String[]) throws java.lang.InterruptedException;
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=3, locals=2, args_size=1
0: new #2 // class java/lang/Integer
3: dup
4: bipush 11
6: invokespecial #3 // Method java/lang/Integer."<init>":(I)V
9: invokevirtual #4 // Method java/lang/Integer.intValue:()I
12: istore_1
13: return
Through analysis, it can be found that the automatic unboxing is actually the conversion completed by the compiler calling the Integer.intValue() method
focus method
valueOf method
public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }
IntegerCache is a static inner class, mainly used to cache the wrapper class of numbers between low and high
private static class IntegerCache { static final int low = -128; static final int high; static final Integer cache[]; static { // high value may be configured by property int h = 127; String integerCacheHighPropValue = sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high"); if (integerCacheHighPropValue != null) { try { int i = parseInt(integerCacheHighPropValue); i = Math.max(i, 127); // Maximum array size is Integer.MAX_VALUE h = Math.min(i, Integer.MAX_VALUE - (-low) -1); } catch( NumberFormatException nfe) { // If the property cannot be parsed into an int, ignore it. } } high = h; cache = new Integer[(high - low) + 1]; int j = low; for(int k = 0; k < cache.length; k++) cache[k] = new Integer(j++); // range [-128, 127] must be interned (JLS7 5.1.7) assert IntegerCache.high >= 127; } private IntegerCache() {} }
It can be seen from the above source code that IntegerCache has three static files modified by final plus a static block and a private constructor; a very simple and common class, the cached wrapper class is between low - high, low The value has been hard-coded -128, and the value of high is determined by your virtual machine sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high"), since it is a parameter, it means that you can dynamically Settings, specifically how to set up Baidu. Then in the loop, the boxed method cache[] of the numbers between low and high is stored in the array of type Integer. This completes the cache
In daily coding, we need to pay attention to the problem of Integer cache
Integer a = 100;
Integer b = 100;
Integer f = Integer.valueOf(100);
Integer c = 200;
Integer d = 200;
System.out.println(a == b);//true
System.err.println(a == f); // true
System.out.println(c == d);//false
- The method stringSize(int x)
is very interesting. I think you can look at this method alone. The main function is to judge the number of digits of a number, but it is used very cleverly.
final static int [] sizeTable = { 9, 99, 999, 9999, 99999, 999999, 9999999,
99999999, 999999999, Integer.MAX_VALUE };
// Requires positive x
static int stringSize(int x) {
for (int i=0; ; i++)
if (x <= sizeTable[i])
return i+1;
}
- equals(Object obj)
It should be noted that Integer also rewrites equals(Object obj), so if the value types compared are Integer, equals() and == have the same effect
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
我们可以写个例子测试下:
Integer num = new Integer(999);
System.err.println(num ==999);
public static void main(java.lang.String[]) throws java.lang.InterruptedException;
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=3, locals=2, args_size=1
0: new #2 // class java/lang/Integer
3: dup
4: sipush 999
7: invokespecial #3 // Method java/lang/Integer."<init>":(I)V
10: astore_1
11: getstatic #4 // Field java/lang/System.err:Ljava/io/PrintStream;
14: aload_1
15: invokevirtual #5 // Method java/lang/Integer.intValue:()I
18: sipush 999
21: if_icmpne 28
24: iconst_1
25: goto 29
28: iconst_0
29: invokevirtual #6 // Method java/io/PrintStream.println:(Z)V
32: return
It can be seen that it is actually unboxing and then comparing the values