int是个很常用的基本类型,Integer是int的包装类型,也是很常用的,那么我们就深入去了解一下Integer内部的原理吧。本来想的是从头到尾的阅读,发现并不靠谱,哈哈哈,对于自己来说,比较懵,还是从常用的方法入手吧。
1.首先看一下integer的最小值和最大值
//看的出这个地方是JVM的本地方法,依赖于操作系统,一般来说是2的31次方的相反数
@Native public static final int MIN_VALUE = 0x80000000;
//同上,2的31次方-1
@Native public static final int MAX_VALUE = 0x7fffffff;
2.integer对象的生成
Integer i1=129;
Integer i2=127;
Integer i3=new Integer(3);
这样就能够生成Integer的对象了,是不是和string有点类似啊,但是对象不是只能通过new、流、clone、反射的方式获得吗?
那么java的自动装箱是怎么样的喃?下面这段代码就是自动装箱的代码。
public static Integer valueOf(int i) {
//读名字,也能够猜出IntegerCache是一个缓存区,是为了提高效率,节约空间的做法
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
接下去看一下缓存
private static class IntegerCache {
static final int low = -128;//最小值
static final int high;//最大值,在static中可以看出是127
static final Integer cache[];//缓存数组
static {
// high value may be configured by property
int h = 127;
//这段代码是 代表,high的值可以配置的
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() {}
}
那么就知道了,integer的对象是这样来的
(1)先判断是否在-128到127(最大值可以配置)之间
(2)如果在的话,就从缓存里面取出来,如果不在的话,就new一个对象
(3)如果是new对象的话,会给Integer内部的一个int赋值为i
3.toString()方法
public String toString() {
//value就是上面说的Integer的成员变量 等于i
return toString(value);
}
public static String toString(int i) {
//如果i等于最小值 就直接返回2的31次方的负数
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);
}
//判断string的长度,例如1->1,10->2
static int stringSize(int x) {
for (int i=0; ; i++)
if (x <= sizeTable[i])
return i+1;
}
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>65536时,得到其后两位,从后往前放入数组里
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;
}
}
4.valueOf(Strings s)方法
以前用valueOf(Strings s)和parseInt(Strings s)的时候并不能感觉到两者有什么差别,就是觉得差不多的,那么接下来就从源码的角度来看一下两者的区别。
public static Integer valueOf(String s) throws NumberFormatException {
//接下来看一下parseInt(String,int)
return Integer.valueOf(parseInt(s, 10));
}
public static int parseInt(String s, int radix) throws NumberFormatException{
if (s == null) {
throw new NumberFormatException("null");
}
//Character.MIN_RADIX=2 最少是2进制
if (radix < Character.MIN_RADIX) {
throw new NumberFormatException("radix " + radix +
" less than Character.MIN_RADIX");
}
//Character.MIN_RADIX=36 最多是36进制
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();
int limit = -Integer.MAX_VALUE;
int multmin;
int digit;
if (len > 0) {
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) // 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;
}
} else {
throw NumberFormatException.forInputString(s);
}
return negative ? result : -result;
}
}
然后接着去valueOf(int)方法。
接下来看一parseInt(String)方法。
public static int parseInt(String s) throws NumberFormatException {
return parseInt(s,10);
}
后面的其实就是一样的了,所以,自己感觉得话会觉得parseInt如果不走缓存的话,那么效率可能会高一点。
5.hashCode()
public int hashCode() {
return Integer.hashCode(value);
}
//也就是返回该值
public static int hashCode(int value) {
return value;
}
6.equals()
public boolean equals(Object obj) {
//先判断obj是不是integer
if (obj instanceof Integer) {
//对比值
return value == ((Integer)obj).intValue();
}
return false;
}
public int intValue() {
return value;
}
以后用到其他方法的时候再来拓展