Java source code to read -Integer (based on jdk1.8)

public final class Integer extends Number implements Comparable<Integer>

  Integer modified by the final, so the class can not be inherited, inherited simultaneously Integer Number class, it can be converted into Integer int, double, float, long, byte and data of type short, Further, to achieve the comparable interfaces, Thus Integer class may be natural ordering.

  Constructors are only two:

public Integer(int value) {
        this.value = value;
    }
public Integer(String s) throws NumberFormatException {
        this.value = parseInt(s, 10);
    }

  We mainly look at the second constructor, passing in a string, and then call parseInt method, then enter parseInt source:

  

public static int parseInt(String s, int radix)
                throws NumberFormatException
    {
        /*
         * WARNING: This method may be invoked early during VM initialization
         * before IntegerCache is initialized. Care must be taken to not use
         * the valueOf method.
         */

        if (s == null) {
            throw new NumberFormatException("null");
        }

        if (radix < Character.MIN_RADIX) {
            throw new NumberFormatException("radix " + radix +
                                            " less than Character.MIN_RADIX"); }
 IF (the radix> Character.MAX_RADIX) {a NumberFormatException the throw new new ( "the radix" the radix + + "Within last Character.MAX_RADIX Greater" );} int Result = 0 ; // // whether to false negative = negative Boolean ; int I = 0 , len = s.length (); // this minus-sign is to prevent data overflow, int value range of -2 31 th power minus a power int limit = 31 to 2 - Integer.MAX_VALUE; // minimum base int multmin; decimal // int digit for; IF (len> 0 ) {char FirstChar = s.charAt (0 ); // the first character is less than 0, there may be "-", "+" or other characters if (firstChar < '0') {// Possible leading "+" or "-" // is negative IF (FirstChar == '-' ) = {negative to true ; = limit of Integer.MIN_VALUE;} the else IF (FirstChar! = '+') // not a number the throw a NumberFormatException.forInputString(s); if (len == 1) // Cannot have lone "+" or "-" throwNumberFormatException.forInputString (S); I ++ ;} / * ** minimum cardinality, primarily prevents result * = radix; the * operation data is too large result in data loss problem because it is 32-bit signed integer type int ~ -2147483648 * 2147483647 / multmin = limit / radix; the while (I < len) {// Accumulating negatively avoids Surprises near MAX_VALUE // decimal conversion, there is obtained the corresponding binary radix decimal numbers, such as: // Character .digit ( 'a', 16) , 10 return; // if the input character is not in the hexadecimal range, the returned -1: //Character.digit('t',16), returns -1, character .digit ( 'a', 10) , = digit for the Character.digit -1 (s.charAt (I ++ ), the radix); // illegal character described -1 IF (digit for <0 ) {the throw NumberFormatException.forInputString (S );} // exceeds the data range IF (Result < multmin) {the throw NumberFormatException.forInputString (S);} / ** * high conversion when converting from the direction of position * / Result * = the radix; IF (Result <limit + digit) { throw NumberFormatException.forInputString(s); } result -= digit; } } else { throw NumberFormatException.forInputString(s); } return negative ? result : -result; }

  This method is the core of step 1, result * = radix; 2, result - = digit; After these two steps to convert the string to a numeric type. Probably process is this:

  If the character string "1234" is converted to type int, result of the initial value 0, radix defaults to 10;

  First, the first character string taken 1 (omitted here various checks), after the first step calculation result = 0 * 10 = 0; second calculating section result = 0 - 1 = -1;

  After the first pass cycle, the result value becomes -1

  Intercepting the second character 2, result = -1 * 10 = -10, result = -10 - 2 = -12;

  Taken third character 3, result = -12 * 10 = -120, result = -120 - 3 = -123;

  Taken fourth character 4, result = -123 * 10 = -1230, result = -1230-4 = -1234;

   End of cycle, when a value of -1234 result, the string to complete the conversion of the integer, is negated to return.

 

  Now I will face questions leads to a problem, then solve the problem by reading the source code.

public static void main(String[] args) {
        Integer i1 = 100;
        Integer i2 = 100;
        Integer i3 = 200;
        Integer i4 = 200; Integer.valueOf i5 = Integer (100 ); I6 = Integer Integer.valueOf (100 ); i7 = new new Integer Integer (100 ); System.out.println ( "i1 == i2 result is:" + (i1 == i2)); System.out.println ( "i3 == i4 result is:" + (== I3 I4)); System.out.println ( "i5 == i6 result is:" + (i5 == i6)); System.out.println ( "i1 == i5 result is:" + (i1 == i5)); System.out.println ( "i1 == i7 result is:" + (i1 == i7));}

Operating results as follows:

Results i1 == i2 are: true 
result i3 == i4 are: false 
result is i5 == i6: true 
result i1 == i5 are: true  result i1 == i7 are: false

  Let's look at the first and the second result, also comparing two identical values, why is there a different result? I took to explain by source.

  First of all, we get to bytecode class files compiled by

  We can see from the figure, in the implementation of Integer i1 = 100 this command, the compiler will call the static method valueOf Integer in, let's take a look at valueOf method is how to achieve it.

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

  This code looks simple, Integer class has a static inner IntegerCache, first determines when the method is called if the value is within the range of the cache, the cache directly to the value returned if otherwise a new object. We seem to see here already know the answers to the above questions, the next static inner classes continue to look at it

 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 // range minimum cache (and default range) (-128) to 127, if the configuration java.lang.Integer.IntegerCache.high // high value may be read from the configuration file 127 H = int ; String integerCacheHighPropValue = sun.misc.VM.getSavedProperty ( "java.lang.Integer.IntegerCache.high" ); IF (integerCacheHighPropValue = null! ) the try { {int I = the parseInt (integerCacheHighPropValue); // Get profile and a maximum value i = Math.max between 127 (i, 127 ); // // Integer.MAX_VALUE the maximum Array iS maximum size range h = Math.min (i, Integer.MAX_VALUE - (-low) -1 );} the catch (a NumberFormatException NFE) {// the If Not The CAN BE Property of Parsed INTO AN int, the ignore IT. }} High = H; // Create new new Integer = buffer array cache [(High - Low) +. 1 ] ; int J = Low; // default digital cached for 127 ~ -128 (K int = 0; K <cache.length; K ++ ) cache [K] = new new Integer (J ++); // range [-128, 127] must be interned (JLS7 5.1.7) assert IntegerCache.high >= 127; } private IntegerCache() {} }

  We will only know the inner class is instantiated class is instantiated when the lies, and will only instantiated once, cache operations are completed in a static block of code, that is to say the class is instantiated when the data is already cached good , and took the time to use the cached data can be used directly.

  Now we return to the above problems, the two figures are the result of 1 100, in the range of cache, so i1 and i2 are pointing to the same memory address, it returns true. Results of the two numbers are 200, beyond the scope of the cache, so that a direct two new objects, so they are inconsistent with the memory address, returns a value of false; Further, use = valueOf and use the same operator when the assignment , so the results 3 and 4 results return to true, the result is 5 direct object is created with the new keyword, so they certainly inconsistent memory address, the result is false.

  Well, now the question again, how do I determine the size of two integers do? Continue to look at the source code

 
 
/**
* The value of the {@code Integer}.
*
* @serial
*/
private final int value;
public boolean equals(Object obj) {
        if (obj instanceof Integer) {
            return value == ((Integer)obj).intValue();
        }
        return false;
    }
public int intValue() {
return value;
}
 

  Yes, it is, can be compared using the method of comparing two values ​​equals the size of the source code is int type value, intValue value is returned, it is possible to determine the size of the two numbers.

public static void main(String[] args) {
        Integer i1 = 200;
        Integer i2 = 200;
        System.out.println ( "i1 == i2 result is:" + i1.equals (i2)); // true
    }

  Supplementary: equals and == difference:

  equals the size comparison of two values, ==, there are two cases, if the comparison is the basic data types, are relatively == like equals the size, or if the array is a reference type, then comparing the memory address.

 

  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;} // // Iteration the Generate TWO digits per each two-digit while (i> = 65536 cycles after acquisition ) {I = Q / 100 ; // Really: R & lt = I - (q * 100); // use efficiency is higher than the shift operation multiplication, r is the last two digits I = R & lt - ((Q <<. 6) + (Q <<. 5) + (Q << 2 ) ); I = Q; // get the digit bits buf [--charPos] = DigitOnes [R & lt]; // ten buf [--charPos] = DigitTens [R & lt];} // Fall to Thru fast mode for smaller numbers // assert ( i <= 65536, i); // get a digit a time for (;;) {// corresponds to i * (52429/524288) = i * 0.10000038146972656 = i * 0.1 = i / 10 // 19, and this power is selected from 52,429 divided by 2, the result obtained is even higher accuracy, the results closer i / 10 // the reason for this conversion, because displacement in a computer calculation efficiency> multiplication efficiency> division efficiency = Q (I * 52429) >>> (+ 16. 3 ); R & lt = I - ((Q <<. 3) + (Q <<. 1)); R & lt // = I- ( 10 * Q) ... buf [--charPos] = digits [R & lt]; I = Q;if (i == 0) break; } if (sign != 0) { buf [--charPos] = sign; } }

   

Guess you like

Origin www.cnblogs.com/rainple/p/10965225.html