这里主要通过阅读源码了解character的一些特性
Character类的结构
public final
class Character implements java.io.Serializable, Comparable<Character> {
……………………
private final char value;
}
可以看到类无法覆盖父类,同时实现了序列化接口和比较接口。存储内容的char型变量为final,无法被修改值。
这里有一个很有意思的类CharacterCache,代码如下:
private static class CharacterCache {
private CharacterCache(){}
static final Character cache[] = new Character[127 + 1];
static {
for (int i = 0; i < cache.length; i++)
cache[i] = new Character((char)i);
}
}
仔细观察接下去的代码我们可以知道,这个类相当于字符集合的一个缓存机制。这里有一个类方法(工厂方法)可以产生Character对象,首先将从cache中取值。
public static Character valueOf(char c) {
if (c <= 127) { // must cache
return CharacterCache.cache[(int)c];
}
return new Character(c);
}
Integer类的结构
public final class Integer extends Number implements Comparable<Integer> {
private final int value;
…………………………
public Integer(int value) {
this.value = value;
}
public Integer(String s) throws NumberFormatException {
this.value = parseInt(s, 10);
}
}
// 可以看到比较值的运算时直接使用值的
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);
}
这里可以看到Integer主要的内容存储方式是和Character极为相似的,除此之外,Integer也有Cache。
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) {
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() {}
}
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
这里可以看到Integer同样有cache,也同样有工厂方法在产生对象的时候使用cache中存储的变量。这里的大小是-128——127。
Integer的一些特性
// 用于数字字符串的转换
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);
}
// 我们可以知道int类型是四个字节32位的数
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] = '-';
}
//根据内容创建新的String类型对象
return new String(buf, charPos, (33 - charPos));
}
上述的是普通的toString,从函数体中我们看到当radix==10使,显然使用的是其他的策略。
public static String toString(int i) {
if (i == Integer.MIN_VALUE)
return "-2147483648";
//StringSize缓存9、99……的int表,从而返回相应的int类型长度
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;
}
// Generate two digits per iteration
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;
}
}
总结
1.Character和Integer都有缓存机制,character为0——127、Integer为-128——127。
2.Integer类型的toString过程中显然用缓存字符矩阵的方法提高效率。此外,可以发现,源码的扩大十倍可以用等价的位运算来替代。