JDK1.8 source code (2)-java.lang.Integer class

Posted May 28, 20206 min read

In the previous blog, we introduced the Object class under the java.lang package, then this blog then introduces another very common class Integer under the package.

1. Statement of Integer

public final class Integer extends Number implements Comparable <Integer> {}

Integer is a constant class declared with final and cannot be inherited by any class. And the Integer class inherits the Number class and implements the Comparable interface. The Number class is an abstract class. Except for Character and Boolean, which do not inherit this class, the wrapper classes of the 8 basic data types inherit the Number class. The methods of this class are used for the conversion of various data types. The Comparable interface is a compareTo method, which is used for size comparison between elements. These methods will be described in detail below.

2. The main attributes of Integer


Int type occupies 4 bytes in Java, so it can represent the size range is -2 31 2 31 -1 is -2147483648 2147483647, we must not exceed this range when using int to represent the value.

3.Constructor Integer(int) Integer(String)

public Integer(int var1) {
    this.value = var1;
}

For the second construction method Integer(String) is to convert the string data we input into integer data.

First of all, we must know that the string that can be converted into an integer must be divided into two parts:the first digit must be "+" or "-", and the rest must be 0-9 and a-z characters

public Integer(String s) throws NumberFormatException {
    this.value = parseInt(s, 10); //First call the parseInt(s, 10) method, where s represents the string we need to convert, 10 means output in decimal, the default is also decimal
}

public static int parseInt(String s, int radix) throws NumberFormatException {
    //If the converted string is null, throw a null pointer exception directly
    if(s == null) {
        throw new NumberFormatException("null");
    }
    //If the converted radix(the default is 10) <2, a number format exception is thrown, because the minimum number is hexadecimal
    if(radix <Character.MIN_RADIX) {
        throw new NumberFormatException("radix" + radix +
                                        "less than Character.MIN_RADIX");
    }
    //If the converted radix(the default is 10)> 36, a number format exception is thrown, because a total of 10 digits from 0 to 9 and a total of 26 digits from a to z, so a total of 36 digits
    //that is, the highest can only have 36 hexadecimal numbers
    if(radix> Character.MAX_RADIX) {
        throw new NumberFormatException("radix" + radix +
                                        "greater than Character.MAX_RADIX");
    }
    int result = 0;
    boolean negative = false;
    int i = 0, len = s.length(); //len is the length of the string to be converted
    int limit = -Integer.MAX_VALUE; //limit = -2147483647
    int multmin;
    int digit;
    //If the length of the string to be converted is greater than 0
    if(len> 0) {
        char firstChar = s.charAt(0); //Get the first character of the string to be converted
        //This is mainly used to judge whether the first character is "+" or "-", because the ASCII code of these two characters is less than the character '0'
        if(firstChar <'0') {
            if(firstChar == '-') {//If the first character is '-'
                negative = true;
                limit = Integer.MIN_VALUE;
            } else if(firstChar! = '+') //If the first character is not '+', directly throw an exception
                throw NumberFormatException.forInputString(s);

            if(len == 1) //The length of the character to be converted is 1, can not be a separate "+" or "-", otherwise an exception
                throw NumberFormatException.forInputString(s);
            i ++;
        }
        multmin = limit/radix;
        //After continuously looping, after removing the first character of the string, it is continuously multiplied according to the hexadecimal to add a positive integer
        //For example parseInt("2abc", 16) = 2 * 16 to the 3rd power + 10 * 16 to the 2nd power + 11 * 16 + 12 * 1
        //parseInt("123", 10) = 1 * 10 to the power of 2 + 2 * 10 + 3 * 1
        while(i <len) {
            digit = Character.digit(s.charAt(i ++), radix);
            if(digit <0) {
                throw NumberFormatException.forInputString(s);
            }
            if(result <multmin) {
                throw NumberFormatException.forInputString(s);
            }
            result * = radix;
            if(result <limit + digit) {
                throw NumberFormatException.forInputString(s);
            }
            result-= digit;
        }
    } else {//If the length of the string to be converted is less than or equal to 0, directly throw an exception
        throw NumberFormatException.forInputString(s);
    }
    //According to the sign of the first character, add a symbol in front of the result
    return negative? result:-result;
}

4, toString() toString(int i) toString(int i, int radix)

These three methods are overloaded and can return a string represented by an integer data. The last method toString(int, int) The second parameter is the hexadecimal number.

public String toString() {
    return toString(value);
}

public static String toString(int i) {
    if(i == Integer.MIN_VALUE)
        return "-2147483648";
    int size =(i <0)? stringSize(-i) + 1:stringSize(i);
    char []buf = new char [size];
    getChars(i, size, buf);
    return new String(buf, true);
}

The toString(int) method internally calls the stringSize() and getChars() methods. stringSize() is used to calculate the number of digits of the parameter i, that is, the length of the string after it is converted into a string. Int type array sizeTable to complete this calculation.

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;
    }

The form of realization is very clever. Note that negative numbers contain sign bits, so the number of bits for negative numbers is stringSize(-i) + 1.

Look at the getChars method:

static void getChars(int i, int index, char []buf) {
        int q, r;
        int charPos = index;
        char sign = 0;

        if(i <0) {
            sign = '-';
            i = -i;
        }

        //Generate two digits per iteration
        while(i> = 65536) {
            q = i/100;
        //really:r = i-(q * 100);
            r = i-((q << 6) +(q << 5) +(q << 2));
            i = q;
            buf [--charPos]= DigitOnes [r];
            buf [--charPos]= DigitTens [r];
        }

        //Fall thru to fast mode for smaller numbers
        //assert(i <= 65536, i);
        for(;;) {
            q =(i * 52429) >>>(16 + 3);
            r = i-((q << 3) +(q << 1)); //r = i-(q * 10) ...
            buf [--charPos]= digits [r];
            i = q;
            if(i == 0) break;
        }
        if(sign! = 0) {
            buf [--charPos]= sign;
        }
    }

I:the number being initialized,

Index:the length of this number(including the negative sign "-"),

Buf:a container of strings-a char type array.

The first if judgment, if i <0, sign writes down its symbol "-", and at the same time converts i into an integer. All the following operations are only for integers, and finally, if you judge that sign is not equal to zero, put your value of sign in the first position of the char array buf \ [-charPos ]= sign ;.

5. Automatic unpacking and packing

Automatic unboxing and automatic boxing is a function only available after JDK1.5, which is one of the many syntactic sugars in java. Its execution is at compile time, and it will be decided when the class file is generated according to the syntax of the code. Whether to carry out unboxing and packing operations.

** , automatic packing**
We know that to create an object of a class, you need to pass the new keyword, for example:

Object obj = new Object();

But in fact, for the Integer class, we can directly use it like this:

Integer a = 128;

Why is this possible? Through decompilation tools, we can see that the generated class file is:

Integer a = Integer.valueOf(128);

We can look at the valueOf() method

public static Integer valueOf(int i) {
    assert IntegerCache.high> = 127;
    if(i> = IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache [i +(-IntegerCache.low)];
    return new Integer(i);
}

In fact, the last thing returned is the object generated by new Integer(), but here should pay attention to the previous code, when the value of i -128 <= i <= 127 returns the object in the cache class, and did not re-create a new The object of this, we should pay attention when comparing through equals.

This is the automatic packing of basic data types, 128 is the basic data type, and then parsed into Integer class.

** , automatic unboxing**
We assign the data represented by the Integer class to the basic data type int, and then perform automatic unboxing.

 Integer a = new Integer(128);
 int m = a;

Class files generated by decompilation:

 Integer a = new Integer(128);
 int m = a.intValue();

Simply put:automatic boxing is Integer.valueOf(int i); automatic unboxing is i.intValue();

6. The equals(Object obj) method

public boolean equals(Object obj) {
    if(obj instanceof Integer) {
        return value ==((Integer) obj) .intValue();
    }
    return false;
}

This method is very simple, first judge the relationship between the two comparison objects by the instanceof keyword, and then force the object to Integer, through automatic unboxing, converted into two basic data classes int, and then == comparison.

7, hashCode() method

     public int hashCode() {
         return value;
     }

The hashCode method of the Integer class is relatively simple, and directly returns the data of its int type.

8, parseInt(String s) and parseInt(String s, int radix) methods

In the past, toString(int i) can convert integer data to string type output. Here, parseInt(String s) can convert the string to integer output.

We have explained these two methods in detail when introducing the constructor Integer(String s).

9, compareTo(Integer anotherInteger) and compare(int x, int y) methods

     public int compareTo(Integer anotherInteger) {
         return compare(this.value, anotherInteger.value);
     }

CompareTo method directly calls the compare method:

     public static int compare(int x, int y) {
        return(x <y)? -1:((x == y)? 0:1);
     }

If x <y returns -1

If x == y returns 0

If x> y returns 1

 System.out.println(Integer.compare(1, 2)); //-1
 System.out.println(Integer.compare(1, 1)); //0
 System.out.println(Integer.compare(1, 0)); //1

So basically the main methods of the Integer class have been introduced so much. If there are more important ones later, they will be updated.

Reference documents:
https://docs.oracle.com/javas...

This series of tutorials is continuously updated, you can search for "IT Coke" on WeChat for the first time. Reply "E-book" has the book material that I specially selected for everyone