Long 源码解析
- 继承自 Number, Comparable
- 属性 final long value
- minValue ~ maxValue = (-2^63 ) ~ (2^63 -1)
- 可类比Integer, Short; 但Float,Double 等没有Cache这一说 缓存 (-128~127)
- 装箱: -128~127 自动拆箱, >127 || <-128 自动装箱
1. LongCache
-
缓存 -128 ~ 127 的值, valueOf
private static class LongCache { private LongCache(){} //缓存-128~127 static final Long cache[] = new Long[-(-128) + 127 + 1]; static { for(int i = 0; i < cache.length; i++) cache[i] = new Long(i - 128); } }
2. parseLong
/**
* s 字符串
* radix 字符串进制类型 范围 2~36, 对应字符串的进制
**/
public static long parseLong(String s, int radix)
throws NumberFormatException
{
if (s == null) {
throw new NumberFormatException("null");
}
// 2 进制 即 char x = '0' || '1' radix最小值为2
if (radix < Character.MIN_RADIX) {
throw new NumberFormatException("radix " + radix +
" less than Character.MIN_RADIX");
}
// 36 因为可以在数值于字符串转换的范围是 0-9 a-z 共计 36
if (radix > Character.MAX_RADIX) {
throw new NumberFormatException("radix " + radix +
" greater than Character.MAX_RADIX");
}
long result = 0;
boolean negative = false;
int i = 0, len = s.length();
long limit = -Long.MAX_VALUE;
long multmin;
int digit;
if (len > 0) {
char firstChar = s.charAt(0);
//判定是否为负数
if (firstChar < '0') { // Possible leading "+" or "-"
if (firstChar == '-') {
//标识符 true 负数, false 正数
negative = true;
limit = Long.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;
}
3. valueOf
/**
* 注意返回值是Long
**/
public static Long valueOf(String s, int radix) throws NumberFormatException {
return Long.valueOf(parseLong(s, radix));
}
/**
* 注意返回值是Long, 默认是10进制
**/
public static Long valueOf(String s) throws NumberFormatException
{
return Long.valueOf(parseLong(s, 10));
}
/**
* 注意返回值是Long, 其适用于 -128~127 范围内的数值型计算,其会自动拆箱
* new Long(1)等同于 final long value = 1L;
**/
public static Long valueOf(long l) {
final int offset = 128;
if (l >= -128 && l <= 127) { // will cache
return LongCache.cache[(int)l + offset];
}
return new Long(l);
}
4. 彩蛋
- Long.parseLong, Long.valueOf的适用场景
- a) 字符串转long数值型, 无论是采用 Long.valueOf,还是Long.parseLong 均可
- b) 针对于包装类Long,用于对象的处理,采用Long.valueOf
- c) 针对于-128~127的long数值型, 建议采用Long.valueOf,其次才是long 因为LongCache有对-128~127的缓存,是常量池的数据
- d) 结论 针对于long的操作,无论是String, long, 还是Long 的场景,Long.valueof更是一种万金油的方法,同时兼顾了性能
5. Long的使用样例
- 结果为True的场景
a) Long n1 = 124L; Long n2 = 124L; n1 == n2;
b) long n3 = 124L; Long n4 = 124L; n3 == n4; //自动拆箱
- 结果为False的场景
a) Long n1 = 128L; Long n2 = 128L; n1 == n2;
b) long n3 = 128L; Long n4 = 128L; n3 == n4; //自动装箱
c) Long n5 = new Long(128); Long n6 = new Long(128); n5 == n6