java源码解读之Integer
2017-02-19 22:04
351 查看
每天都在用着Java各种各样的类与方法,但是也仅仅只是局限于用,却不了解那些每天都接触的类与方法内部是如何去实现的,遇到问题只能不停地度娘谷歌看文章,因此决定从现在开始学习jdk的源码,我相信基础的东西永远都不会过时,不仅要知其然,还要知其所以然。
先从我们平常用的最多的数据类型入手,最常见的莫过于Integer类型,本篇文章就对Integer的源码常用的方法进行解读,源码去掉了多余且看得一脸懵逼的英文注释,所有的分析都写在源码上,无需一边看字一边看代码啦,下面开始放大招“祭出源码”啦
。
package java.lang; import java.util.Properties; /** * Integer类被final修饰,因此该类是不可被继承 */ public final class Integer extends Number implements Comparable<Integer> { /** * Integer 可以取到的最小值,十六进制形式为0x80000000,二进制即为-2147483648(-2^31) */ public static final int MIN_VALUE = 0x80000000; /** * 也就是说Integer的取值范围是[-2147483648,2147483647],超过则溢出,需要更大的数据类型来存储 */ /** * Integer 可以取到的最大值,十六进制形式为0x7fffffff,二进制即为2147483647(2^31-1) */ public static final int MAX_VALUE = 0x7fffffff; /** * 记录该基本类型包装类所对应的基本数据类型(如:Integer对应int,Double对应double等) */ public static final Class<Integer> TYPE = (Class<Integer>) Class.getPrimitiveClass("int"); /** * 存放所有可能被用来代表数字的字符 */ 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' }; /** * 以字符串的形式返回指定int类型数字对应的radix进制数的表示形式 */ public static String toString(int i, int radix) { //若radix进制数超出指定范围[2,36],则radix设置为默认的10进制 if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) radix = 10; /* Use the faster version */ if (radix == 10) { //若是radix进制数为10,则直接返回即可,因为默认就是10进制数的 return toString(i); } //radix进制数既不是10也不超出指定范围,则执行进制转换的运算,用求余运算 i%radix char buf[] = new char[33]; boolean negative = (i < 0); int charPos = 32; //若该数字i为正数,则转换成-i,防止溢出,用负数来进行运算 if (!negative) { i = -i; } //这里循环进行求余运算 while (i <= -radix) { //由于前面将i转换成负数,故求余得到的余数前面需再多个负号(负负得正嘛,数组下标总不能为负的啦) buf[charPos--] = digits[-(i % radix)]; i = i / radix; } buf[charPos] = digits[-i]; //这里将数字的正负还原 if (negative) { buf[--charPos] = '-'; } //返回数字i指定进制数的字符串 String(char value[],int start,int count) return new String(buf, charPos, (33 - charPos)); } /** * 将指定int数字i转换为16进制数字符串 */ public static String toHexString(int i) { return toUnsignedString(i, 4); } /** * 将指定int数字i转换为8进制数字符串 */ public static String toOctalString(int i) { return toUnsignedString(i, 3); } /** * 将指定int数字i转换为2进制数字符串 */ public static String toBinaryString(int i) { return toUnsignedString(i, 1); } /** * 将指定int数字i转换为无符号的字符串 */ private static String toUnsignedString(int i, int shift) { char[] buf = new char[32]; int charPos = 32; int radix = 1 << shift;//左移运算,相当于1乘以2^shift int mask = radix - 1; do { //与运算,i跟mask的二进制数进行与运算,用运算结果进行查表后赋值给char数组 buf[--charPos] = digits[i & mask]; i >>>= shift;//i进行右移后赋值运算,最高位都补0 } while (i != 0); //直到i等于0以字符串形式返回计算结果 String(char value[],int start,int count) return new String(buf, charPos, (32 - charPos)); } //存储十位数以上的字符集,用于下面方法求余运算快速算出十位上的数值 final static char [] DigitTens = { '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '6', '6', '6', '6', '6', '6', '6', '6', '6', '6', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '8', '8', '8', '8', '8', '8', '8', '8', '8', '8', '9', '9', '9', '9', '9', '9', '9', '9', '9', '9', } ; //存储个位数以上的字符集,用于下面方法求余运算快速算出个位上的数值 final static char [] DigitOnes = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', } ; public static String toString(int i) { if (i == Integer.MIN_VALUE) return "-2147483648"; //确定数字i是多少位数的 int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i); char[] buf = new char[size]; //计算生成i要返回字符数组 getChars(i, size, buf); //String(int start,int count,char[] value) return new String(0, size, buf); } /** * 当==Integer.MIN_VALUE时将转换失败 * 该方法主要用了以下4个体系结构知识(下文代码以1,2,3,4代表): * 1.乘法比除法高效:除法绝大部分都以乘法+位移运算来替代,如:q = (i * 52429) >>> (16+3); * 2.位移运算比乘法高效:方法中绝大部分的乘法运算都以 << 左移运算替代 * 3.重复利用计算结果: q = i / 100;r = i - ((q << 6) + (q << 5) + (q << 2)); * 4.局部性原理之空间局部性:buf[--charPos] = DigitOnes[r];buf[--charPos] = DigitTens[r]; * 通过以下标查找数组,实现快速访问,避免除法运算 */ static void getChars(int i, int ind 4000 ex, char[] buf) { int q, r; int charPos = index; char sign = 0;//用于记住数字i的符号,+还是- if (i < 0) { sign = '-'; i = -i; } //对于比较大的数字,先迭代求余,每次算出2位数的余数放到字符缓冲区中 while (i >= 65536) { //关于这里的除法为什么不用乘法+位移运算来替代,是因为进入该迭代的数值都是比较 //大的,而int类型最大值为(2^31-1),使用乘法+位移运算容易溢出 q = i / 100; //实际上就是 r = i - (q * 100); r为i/100的余数 q<<6是左移运算,即为q乘以2^6 r = i - ((q << 6) + (q << 5) + (q << 2));//利用到了体系结构知识3 i = q; ////利用到了体系结构知识4 buf [--charPos] = DigitOnes[r];//存储余数r的个位数,即r%10 buf [--charPos] = DigitTens[r];//存储余数r的十位数,即r/10 } //对于较小数字(<= 65536)的快速计算模式 for (;;) { //该表达式利用到了体系结构知识1,2^19=524288,这样能保证在int的范围内计算出来 //的精度最高,即(i*52429)/524288,其中52429/524288=0.10000038146972656, //这也是为什么选择52429余524288这两个数的原因 q = (i * 52429) >>> (16+3); //实际上就是q/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; } } final static int [] sizeTable = { 9, 99, 999, 9999, 99999, 999999, 9999999, 99999999, 999999999, Integer.MAX_VALUE }; //求数字i的位数,不用再像老师教的除以10然后干嘛干嘛啦 static int stringSize(int x) { for (int i=0; ; i++) if (x <= sizeTable[i]) return i+1; } /** * <p>Examples: * <blockquote><pre> * parseInt("0", 10) returns 0 * parseInt("473", 10) returns 473 * parseInt("+42", 10) returns 42 * parseInt("-0", 10) returns 0 * parseInt("-FF", 16) returns -255 * parseInt("1100110", 2) returns 102 * parseInt("2147483647", 10) returns 2147483647 * parseInt("-2147483648", 10) returns -2147483648 * parseInt("2147483648", 10) throws a NumberFormatException * parseInt("99", 8) throws a NumberFormatException * parseInt("Kona", 10) throws a NumberFormatException * parseInt("Kona", 27) returns 411787 * </pre></blockquote> * 将指定radix进制数的字符串转换为10进制的int类型数字 */ public static int parseInt(String s, int radix) throws NumberFormatException { //传递进来的String为null的时候,抛NumberFormatException异常 if (s == null) { throw new NumberFormatException("null"); } //若要转换的进制数不是属于[2,36]的,则同样抛NumberFormatException异常 if (radix < Character.MIN_RADIX) { throw new NumberFormatException("radix " + radix + " less than Character.MIN_RADIX"); } if (radix > Character.MAX_RADIX) { throw new NumberFormatException("radix " + radix + " greater than Character.MAX_RADIX"); } int result = 0; boolean negative = false;//用于标志该字符串数字是"+" or "-" int i = 0, len = s.length(); int limit = -Integer.MAX_VALUE; int multmin; int digit; if (len > 0) { //取字符串s第一个字符,以判断该字符串数字是"+" or "-" char firstChar = s.charAt(0); if (firstChar < '0') { // Possible leading "+" or "-" if (firstChar == '-') { negative = true; limit = Integer.MIN_VALUE; } else if (firstChar != '+') throw NumberFormatException.forInputString(s); if (len == 1) //字符串不能只有一个字符"+" or "-"的 throw NumberFormatException.forInputString(s); i++; } multmin = limit / radix; /** * 这里的迭代举个例子: * "12345"按照十进制转成12345的方法其实就是((1*10)+2)*10)+3)*10+4)*10+5 * 而如何将字符串中每个字符转换成不同进制的int类型数字则是下面
* Character.digit(char ch,int radix)方法的事情了 */ while (i < len) { //逐个字符累积以防止突然就接近Integer的最大值,导致溢出 //使用Character.digit(char ch,int radix)方法将字符串中的
//每个字符转换成不同进制的int类型数字 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 { //String的长度<=0,同样抛NumberFormatException并提示字符串信息 throw NumberFormatException.forInputString(s); } //返回转换后的10进制数字 return negative ? result : -result; } /** * 将字符串数字转换为int类型数字,不填radix进制数则默认字符串s为10进制的数字字符串 */ public static int parseInt(String s) throws NumberFormatException { return parseInt(s,10); } /** * 将字符串数字按照指定的radix进制数转换成int数字 * 先调用parseInt方法将字符串数字转换为int数字,再调用valueOf方法返回Integer对象 */ public static Integer valueOf(String s, int radix) throws NumberFormatException { return Integer.valueOf(parseInt(s,radix)); } /** * 将字符串数字转换成int数字,默认为10进制数字 * 先调用parseInt方法将字符串数字转换为10进制的int数字,再调用valueOf方法返回Integer对象 */ public static Integer valueOf(String s) throws NumberFormatException { return Integer.valueOf(parseInt(s, 10)); } /** * Integer类的内部字符缓冲类,默认情况下缓冲的范围是[-128,127],
* 当我们使用Integer类型的数字时,若该数字处于该范围,则其引用所指
* 向的内存即是该缓冲区的内存,不会开辟新的内存空间,若是超过该范围
* 则开辟新的内存空间 * 这也是为什么人们常说:java中的Integer类型100==100而1000!=1000 * 该缓冲区的大小可以通过参数-XX:AutoBoxCacheMax来设置 */ 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) { int i = parseInt(integerCacheHighPropValue); i = Math.max(i, 127); // Maximum array size is Integer.MAX_VALUE h = Math.min(i, Integer.MAX_VALUE - (-low)); } high = h; cache = new Integer[(high - low) + 1]; int j = low; for(int k = 0; k < cache.length; k++) cache[k] = new Integer(j++); } private IntegerCache() {} } /** * 将int数字转换为Integer对象 */ public static Integer valueOf(int i) { assert IntegerCache.high >= 127; //若int数字的值在Integer类的内部缓冲区的范围内(即[-128,127]),
//则直接从缓冲区返回一个已存在的Integer对象 if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; //若不在缓冲区的范围内,则new一个新的Integer对象返回 return new Integer(i); } /** * 因此,当把一个int变量转成Integer的时候(或者新建一个Integer的时候),
* 建议使用valueOf方法来代替构造函数, * 或者直接使用Integer i = 100;编译器会转成Integer s = Integer.valueOf(10000) * valueOf与parseInt的差别在于valueOf可能会利用到Integer内部的缓冲区 */ /**这里的value属性是真正保存Integer对象的int值的,而且是被final修饰的,也
* 就是说,当一个Integer对象被初始化后,value的值是无法被改变的,即一个已
*初始化的Integer对象中的int值是不可变的,至于在我们一般的程序中Integer
*对象的值可以重新赋值,可以看下面一个简单的代码例子: * Integer i = new Integer(10); * i = 5; * System.out.println(i); * 我们都知道这个打印出来的一定是5,这样不就与我们刚刚说的Integer对象中
*的int值是不可变的相互打脸了么 * 实则不然,将上面的代码反编译之后,会变成如下的样子: * Integer i = new Integer(10); * i = Integer.valueOf(5); * System.out.println(i); * 即i=5会被编译器转换成i=Integer.valueOf(5) * 也就是说,i=5并没有改变使用Integer i = new Integer(10)创建出来的Integer对
* 象i中的value属性的值,而是重新创建(或者从缓冲区返回)一个对象,并将引用i指
* 向新的Integer对象,所以刚刚的说法并无打脸之处 */ private final int value; public Integer(int value) { this.value = value; } public Integer(String s) throws NumberFormatException { this.value = parseInt(s, 10); } public byte byteValue() { return (byte)value; } public short shortValue() { return (short)value; } public int intValue() { return value; } public long longValue() { return (long)value; } public float floatValue() { return (float)value; } public double doubleValue() { return (double)value; } public String toString() { return toString(value); } public int hashCode() { return value; } /** * Integer对象之间的equals其实比的就是int值,所以呢,当2个Integer对象要比较是否相等的话,要么 * 调用equals方法,要么调用intValue方法(a.intValue()==b.intValue())来比较,千万别直接就 * 上"=="比较,之前没注意就被这个给坑死了额 */ public boolean equals(Object obj) { if (obj instanceof Integer) { return value == ((Integer)obj).intValue(); } return false; } /** * 返回具有指定名称的系统属性的整数值,是通过
* System.getProperty(java.lang.String)方法可以访问的系统属性 */ public static Integer getInteger(String nm) { return getInteger(nm, null); } /** * 返回具有指定名称的系统属性的整数值,是通过System.getProperty(java.lang.String)
* 方法可以访问的系统属性, * 如果没有具有指定名称的属性,或者属性的数字格式不正确,或者指定名称为空或null,则
* 返回一个表示第二个参数的值的Integer对象 */ public static Integer getInteger(String nm, int val) { Integer result = getInteger(nm, null); return (result == null) ? Integer.valueOf(val) : result; } /** * 返回具有指定名称的系统属性的整数值,是通过
* System.getProperty(java.lang.String)方法可以访问的系统属性, * 如果没有具有指定名称的属性,或者属性的数字格式不正确,或者指定
* 名称为空或null,则返回一个表示第二个参数的对象 */ public static Integer getInteger(String nm, Integer val) { String v = null; try { //首先通过System.getProperty(String)取得指定名称的系统属性 v = System.getProperty(nm); } catch (IllegalArgumentException e) { } catch (NullPointerException e) { } if (v != null) { try { //若能去得到指定名称的系统属性值,则调用Integer类
//的decode(String)方法将字符串转换为Integer对象 return Integer.decode(v); } catch (NumberFormatException e) { } } return val; } public static Integer decode(String nm) throws NumberFormatException { int radix = 10;//默认的进制数为10进制 int index = 0; boolean negative = false; Integer result; if (nm.length() == 0) throw new NumberFormatException("Zero length string"); char firstChar = nm.charAt(0); // Handle sign, if present //这里通过字符串的第一个字符来判断要返回的Integer是"+" or "-"的 if (firstChar == '-') { negative = true; index++; } else if (firstChar == '+') index++; // Handle radix specifier, if present //这里确定要将字符串转换为多少进制的Integer对象 //若字符串以"0x" or "0X" 开头,则后面将其转换为16进制的Integer对象 if (nm.startsWith("0x", index) || nm.startsWith("0X", index)) { index += 2; radix = 16; } //若字符串以 "#" 开头,则后面同样将其转换为16进制的Integer对象 else if (nm.startsWith("#", index)) { index ++; radix = 16; } //若字符串以 "0" 开头且字符串长度大于2,则后面将其转换为8进制的Integer对象 else if (nm.startsWith("0", index) && nm.length() > 1 + index) { index ++; radix = 8; } //若标志字符串 "+" or "-"的字符出现在错误的位置,则抛NumberFormatException if (nm.startsWith("-", index) || nm.startsWith("+", index)) throw new NumberFormatException("Sign character in wrong position"); try { //这里调用上面的valueOf方法将剩余的字符串转换为指定进制数的Integer对象 result = Integer.valueOf(nm.substring(index), radix); //判断Integer对象是 "+" or "-"并返回转换后的Integer对象 result = negative ? Integer.valueOf(-result.intValue()) : result; } catch (NumberFormatException e) { // If number is Integer.MIN_VALUE, we'll end up here. The next line // handles this case, and causes any genuine format error to be // rethrown. String constant = negative ? ("-" + nm.substring(index)) : nm.substring(index); result = Integer.valueO c583 f(constant, radix); } return result; } /** * 总结下getInteger方法:这个方法是用于获取指定名称的系统属
* 性的整数值,而不是将String类型转换为Integer(PS:一开始 * 我就是这么天真的认为的,直到看了源码O__O "…),要将String转
* 换为Integer/int请使用valueOf/parseInt方法 * 该方法的调用栈是这样的: * getInteger(String nm) ---> getInteger(nm, null);--->
* Integer.decode()--->Integer.valueOf()--->parseInt() * 因此,总结下parseInt、valueOf、decode、getInteger方法: * 如果只需要返回一个基本类型,而不需要一个对象,可以直接使用parseInt方法; * 如果需要一个对象,那么建议使用valueOf方法,因为该方法可以借助缓存带来的好处; * 如果和进制有关,那么就是用decode方法; * 如果是从系统配置中取值,那么就是用getInteger方法 */ /** * Integer对象之间的比较,大于返回1,小于返回-1,等于返回0,实际上
* 就是对Integer中基本数据类型value值的比较 */ public int compareTo(Integer anotherInteger) { return compare(this.value, anotherInteger.value); } public static int compare(int x, int y) { return (x < y) ? -1 : ((x == y) ? 0 : 1); } // Bit twiddling /** * The number of bits used to represent an {@code int} value in two's * complement binary form. * * @since 1.5 */ public static final int SIZE = 32; /** * 返回具有至多单个1位的 int值,在指定的int值中最高位(最左边)的1位的位置 */ public static int highestOneBit(int i) { // HD, Figure 3-1 i |= (i >> 1); i |= (i >> 2); i |= (i >> 4); i |= (i >> 8); i |= (i >> 16); return i - (i >>> 1); } /** * 返回具有至多单个1位的 int值,在指定的int值中最低位(最右边)的1位的位置 */ public static int lowestOneBit(int i) { // HD, Section 2-1 return i & -i; } /** * 在指定int值的二进制补码表示形式中最高位(最左边)的1位之前,返回零位的数量 */ public static int numberOfLeadingZeros(int i) { // HD, Figure 5-6 if (i == 0) return 32; int n = 1; if (i >>> 16 == 0) { n += 16; i <<= 16; } if (i >>> 24 == 0) { n += 8; i <<= 8; } if (i >>> 28 == 0) { n += 4; i <<= 4; } if (i >>> 30 == 0) { n += 2; i <<= 2; } n -= i >>> 31; return n; } /** * 返回指定的int值的二进制补码表示形式中最低(最右边)的为1的位后面的零位个数 */ public static int numberOfTrailingZeros(int i) { // HD, Figure 5-14 int y; if (i == 0) return 32; int n = 31; y = i <<16; if (y != 0) { n = n -16; i = y; } y = i << 8; if (y != 0) { n = n - 8; i = y; } y = i << 4; if (y != 0) { n = n - 4; i = y; } y = i << 2; if (y != 0) { n = n - 2; i = y; } return n - ((i << 1) >>> 31); } /** * 返回指定int值的二进制补码表示形式的1位的数量 */ public static int bitCount(int i) { // HD, Figure 5-2 i = i - ((i >>> 1) & 0x55555555); i = (i & 0x33333333) + ((i >>> 2) & 0x33333333); i = (i + (i >>> 4)) & 0x0f0f0f0f; i = i + (i >>> 8); i = i + (i >>> 16); return i & 0x3f; } /** * 返回根据指定的位数循环左移指定的int值的二进制补码表示形式而得到的值 */ public static int rotateLeft(int i, int distance) { return (i << distance) | (i >>> -distance); } /** * 返回根据指定的位数循环右移指定的int值的二进制补码表示形式而得到的值 */ public static int rotateRight(int i, int distance) { return (i >>> distance) | (i << -distance); } /** * 返回通过反转指 int值的二进制补码表示形式中位的顺序而获得的值 */ public static int reverse(int i) { // HD, Figure 7-1 i = (i & 0x55555555) << 1 | (i >>> 1) & 0x55555555; i = (i & 0x33333333) << 2 | (i >>> 2) & 0x33333333; i = (i & 0x0f0f0f0f) << 4 | (i >>> 4) & 0x0f0f0f0f; i = (i << 24) | ((i & 0xff00) << 8) | ((i >>> 8) & 0xff00) | (i >>> 24); return i; } /** * 返回指定int值的符号函数 */ public static int signum(int i) { // HD, Section 2-7 return (i >> 31) | (-i >>> 31); } /** * 返回通过反转指定int值的二进制补码表示形式中字节的顺序而获得的值 */ public static int reverseBytes(int i) { return ((i >>> 24) ) | ((i >> 8) & 0xFF00) | ((i << 8) & 0xFF0000) | ((i << 24)); } /** use serialVersionUID from JDK 1.0.2 for interoperability */ private static final long serialVersionUID = 1360826667806852920L; }其中,相对比较重要的方法都有比较啰嗦的注释,其余的知道就好啦,无需深究(其实就是我学识短浅深究不了O(∩_∩)O哈哈哈~),以上就是Integer类源码的解读。
铭记初衷,倾己所有
~~~
相关文章推荐
- Java源码解析Integer方法解读
- Java Integer源码解读
- Java源码侦探-Integer方法解读
- java 十六进制 Integer 进制转换 源码解读
- Java HashMap 核心源码解读
- Java源码解读之util.ArrayList .
- JR 精品文章 - Java??2源码解读1:java.util.ArrayList??(版本:2.0)
- Java 2源码解读1:java.util.ArrayList
- Java 2源码解读1:java.util.ArrayList
- OpenJDK源码研究笔记(五)-缓存Integer等类型的频繁使用的数据和对象,大幅度提升性能(一道经典的Java笔试题)
- Java HashMap 核心源码解读
- Java 2源码解读:java.util.ArrayList
- OpenJDK源码研究笔记(五)-缓存Integer等类型的频繁使用的数据和对象,大幅度提升性能(一道经典的Java笔试题)
- java 源码 Integer
- Java 2源码解读:java.util.ArrayList
- Java HashMap 核心源码解读
- Java 2源码解读1:java.util.ArrayList (版本:2.0)
- Java 2源码解读:java.util.ArrayList
- Java源码分析:Integer中的位运算
- (转)Java并发编程总结---Hadoop核心源码实例解读