JDK源碼之Integer
1、Integer類簡介
Integer是int的包裝類,被final修飾,不能被其他類繼承,繼承Number類,Integer重寫了相關方法,如longValue(),floatValue(),doubleValue()等等。Integer類實現了Compare<Integer>接口。
2、源碼
2.1、Integer類的屬性
/** * int 類型能夠表示的最小值 -2^31 * have, -2<sup>31</sup>. */ @Native public static final int MIN_VALUE = 0x80000000; /** * int 類型能夠表示的最大值 2^31 * have, 2<sup>31</sup>-1. */ @Native public static final int MAX_VALUE = 0x7fffffff; /** * int 類型的 calss 實例 * {@code int}. * * @since JDK1.1 */ @SuppressWarnings("unchecked") public static final Class<Integer> TYPE = (Class<Integer>) Class.getPrimitiveClass("int");/** * 二進制補碼形式下 int 的比特位數 * complement binary form. * * @since 1.5 */ @Native public static final int SIZE = 32; /** * 二進制補碼下int的字節數/jdk1.8加入 * complement binary form. * * @since 1.8 */ public static final int BYTES = SIZE / Byte.SIZE;
2.2、Integer類的構造方法
public Integer(int value) { this.value = value; } public Integer(String s) throws NumberFormatException { this.value = parseInt(s, 10); }
共提供兩個構造方法,一個參數為int,將int賦值給value。另外一個為String,通過parseInt方法將字符串轉換為Integer。
2.3、parseInt()方法
public static int parseInt(String s, int radix) throws NumberFormatException { //字符串為空 直接拋出異常 if (s == null) { throw new NumberFormatException("null"); } //小于最小數2 拋出異常 MAX_RADIX = 2 計算機的基礎進制 if (radix < Character.MIN_RADIX) { throw new NumberFormatException("radix " + radix + " less than Character.MIN_RADIX"); } //大于最大數36 拋出異常 MAX_RADIX = 36 表示0-9數字集a-z字母,共36字符 if (radix > Character.MAX_RADIX) { throw new NumberFormatException("radix " + radix + " greater than Character.MAX_RADIX"); } int result = 0;
//標志是否為負數 默認為false boolean negative = false;
//遍歷初始位置i=0 , 字符串長度 int i = 0, len = s.length(); int limit = -Integer.MAX_VALUE; int multmin; int digit; //字符串長度需要大于0 否者直接拋出異常 if (len > 0) {
//字符串第一個字符 char firstChar = s.charAt(0);
//第一個字符是否小于'0'的ASCII的值,說明不符合十進制的數字的合法開頭。有兩個例外 是'+'或'-', if (firstChar < '0') { // Possible leading "+" or "-" if (firstChar == '-') { //如果是'-' negative = true; //負數標志變為true limit = Integer.MIN_VALUE; } else if (firstChar != '+') throw NumberFormatException.forInputString(s); //不是'+' 和 '-' 直接拋出異常 if (len == 1) // Cannot have lone "+" or "-" throw NumberFormatException.forInputString(s); //只有'+' 或 '-' 直接拋出異常 i++; }
// 計算乘法前的最小值,用于后續溢出檢查 multmin = limit / radix; while (i < len) { //遍歷字符串 // Accumulating negatively avoids surprises near MAX_VALUE 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; //使用負數累積 防止MIN_VALUE 的絕對值比 MAX_VALUE大 1的情況 int的取值范圍是-2147483648 至 2147483647 } } else { throw NumberFormatException.forInputString(s); } return negative ? result : -result; //轉換回對應的整數結果 }
2.4、valueOf()方法
public static Integer valueOf(String s, int radix) throws NumberFormatException { return Integer.valueOf(parseInt(s,radix)); } public static Integer valueOf(String s) throws NumberFormatException { return Integer.valueOf(parseInt(s, 10)); } // 根據傳入的int 判斷是否在緩存中,如果在,那么返回緩存中的數據,如果不在,則創建一個新的Integer對象返回 public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }
使用valueOf()涉及到一個自動裝箱的過程,就是把基本數據類型用對應的引用類型包裝起來,使得它們由對象的特質,如double類型包裝為Double,int包裝成Integer類型。
//自動裝箱 int a = 5; Integer b = a; // 編譯器自動轉換為Integer.valueOf(a) //自動拆箱 Integer b = new Integer(5); int a = b; //編譯器自動轉換為 b.intValue()
JDK 5 引入自動裝箱/拆箱 JDK8:增強類型推斷,減少顯示裝箱
2.5、intValue()方法
public int intValue() { return value; }
2.5、toString()方法
final static char[] digits = { //常量數組 '0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' , 'a' , 'b' , 'c' , 'd' , 'e' , 'f' , 'g' , 'h' , 'i' , 'j' , 'k' , 'l' , 'm' , 'n' , 'o' , 'p' , 'q' , 'r' , 's' , 't' , 'u' , 'v' , 'w' , 'x' , 'y' , 'z' }; public static String toString(int i, int radix) {
//非法進制默認使用十進制 if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) radix = 10; /* Use the faster version */ if (radix == 10) { return toString(i); } char buf[] = new char[33]; boolean negative = (i < 0); int charPos = 32; if (!negative) { i = -i; } while (i <= -radix) { buf[charPos--] = digits[-(i % radix)]; i = i / radix; } buf[charPos] = digits[-i]; //添加負號 if (negative) { buf[--charPos] = '-'; } return new String(buf, charPos, (33 - charPos)); } 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); } static void getChars(int i, int index, char[] buf) { int q, r; int charPos = index; char sign = 0; if (i < 0) { sign = '-'; i = -i; } // 處理大數 i >= 2^16 while (i >= 65536) { q = i / 100; // 等價于 r = i - (q * 100); r = i - ((q << 6) + (q << 5) + (q << 2)); i = q; buf [--charPos] = DigitOnes[r]; buf [--charPos] = DigitTens[r]; } // 處理小數 // assert(i <= 65536, i); for (;;) {
//使用魔術數52429 優化除法 52429/2^19 約等于 1/10 q = (i * 52429) >>> (16+3); // q = i/10 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; } }

浙公網安備 33010602011771號