True,JVM会自动维护5种基本数据类型的常量池,int常量池中初始化-128到127的范围,所以当为Integer a = 127时,在自动装箱过程中是取自常量池中的数值,而当Integer a=128时,128不在常量池范围内,所以在自动装箱过程中需new 128,所以地址不一样。
以下是Integer的静态内部类
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer[] cache;
static Integer[] archivedCache;
static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {
h = Math.max(parseInt(integerCacheHighPropValue), 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(h, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
// If the property cannot be parsed into an int, ignore it.
}
}
high = h;
// Load IntegerCache.archivedCache from archive, if possible
CDS.initializeFromArchive(IntegerCache.class);
int size = (high - low) + 1;
// Use the archived cache if it exists and is large enough
if (archivedCache == null || size > archivedCache.length) {
Integer[] c = new Integer[size];
int j = low;
for(int i = 0; i < c.length; i++) {
c[i] = new Integer(j++);
}
archivedCache = c;
}
cache = archivedCache;
// range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127;
}
private IntegerCache() {}
}
VM.getSavedProperty(“java.lang.Integer.IntegerCache.high”);表示缓存范围是可以被修改的
而Byte,Short,Long 有固定范围: -128 到 127,对于 Character, 范围是 0 到 127。
LongCache
private static class LongCache {
private LongCache() {}
static final Long[] cache;
static Long[] archivedCache;
static {
int size = -(-128) + 127 + 1;
// Load and use the archived cache if it exists
CDS.initializeFromArchive(LongCache.class);
if (archivedCache == null || archivedCache.length != size) {
Long[] c = new Long[size];
long value = -128;
for(int i = 0; i < size; i++) {
c[i] = new Long(value++);
}
archivedCache = c;
}
cache = archivedCache;
}
}
CharacterCache
private static class CharacterCache {
private CharacterCache(){}
static final Character[] cache;
static Character[] archivedCache;
static {
int size = 127 + 1;
// Load and use the archived cache if it exists
CDS.initializeFromArchive(CharacterCache.class);
if (archivedCache == null || archivedCache.length != size) {
Character[] c = new Character[size];
for (int i = 0; i < size; i++) {
c[i] = new Character((char) i);
}
archivedCache = c;
}
cache = archivedCache;
}
}
ShortCache
private static class ShortCache {
private ShortCache() {}
static final Short[] cache;
static Short[] archivedCache;
static {
int size = -(-128) + 127 + 1;
// Load and use the archived cache if it exists
CDS.initializeFromArchive(ShortCache.class);
if (archivedCache == null || archivedCache.length != size) {
Short[] c = new Short[size];
short value = -128;
for(int i = 0; i < size; i++) {
c[i] = new Short(value++);
}
archivedCache = c;
}
cache = archivedCache;
}
}
ByteCache
private static class ByteCache {
private ByteCache() {}
static final Byte[] cache;
static Byte[] archivedCache;
static {
final int size = -(-128) + 127 + 1;
// Load and use the archived cache if it exists
CDS.initializeFromArchive(ByteCache.class);
if (archivedCache == null || archivedCache.length != size) {
Byte[] c = new Byte[size];
byte value = (byte)-128;
for(int i = 0; i < size; i++) {
c[i] = new Byte(value++);
}
archivedCache = c;
}
cache = archivedCache;
}
}