Java int & Integer 区别
int
int 是Java的8个原始数据类型(boolean、byte、short、char、int、float、double、long)之一。Java虽然号称是面向对象语言,但原始数据类型是例外。
Integer
Integer 是int 对应的包装类型,它有一个int 类型的字段存储数据,并提供了基本操作,如数学运算、int和字符串之间转换等。在Java 5中,引入自动装箱和自动拆箱功能,Java可以根据上下文环境,自动进行转换,简化了代码。
Integer值缓存
在创建一个Integer对象传统方式是直接new一个对象,但还可以使用静态方法valueOf() 创建,使用该方法会利用一个缓存机制,值默认缓存是-128~127之间,有一定的性能优化。
这种缓存机制不只出现在Integer类,其他的包装类也存在,如:
- Boolean,缓存了true/false。
- Short,同样缓存了-128~127之间的数值。
- Byte,同样缓存-128~127之间。
- Character,缓存
\u0000 到\u007F .
自动装箱、拆箱
自动装箱实际上算是一种语法糖,可以简单理解为Java平台为我们自动进行了一些转换,保证不通的写法在运行时等价,它们发生在编译阶段,生成的字节码是一致的。
- 自动装箱:javac会自动转换为
Integer.valueOf() ,可能会使用缓存。 - 自动拆箱:javac会自动转换为
Integer.intValue() 。
Integer a = 1;
int b = a++;
反编译为
0 iconst_1
1 invokestatic #2 <java/lang/Integer.valueOf : (I)Ljava/lang/Integer;>
4 astore_1
5 aload_1
6 astore_3
7 aload_1
8 invokevirtual #3 <java/lang/Integer.intValue : ()I>
11 iconst_1
12 iadd
13 invokestatic #2 <java/lang/Integer.valueOf : (I)Ljava/lang/Integer;>
16 dup
17 astore_1
18 astore 4
20 aload_3
21 invokevirtual #3 <java/lang/Integer.intValue : ()I>
24 istore_2
25 return
IntegerCache源码分析
Integer的默认缓存范围是-128~127,但是缓存上限值是可以调整JVM的。
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer[] cache;
static Integer[] archivedCache;
private IntegerCache() {
}
static {
int h = 127;
String integerCacheHighPropValue = VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
int size;
if (integerCacheHighPropValue != null) {
try {
size = Integer.parseInt(integerCacheHighPropValue);
size = Math.max(size, 127);
h = Math.min(size, 2147483518);
} catch (NumberFormatException var6) {
}
}
high = h;
VM.initializeFromArchive(Integer.IntegerCache.class);
size = high - -128 + 1;
if (archivedCache == null || size > archivedCache.length) {
Integer[] c = new Integer[size];
int j = -128;
for(int k = 0; k < c.length; ++k) {
c[k] = new Integer(j++);
}
archivedCache = c;
}
cache = archivedCache;
assert high >= 127;
}
}
ShortCache源码分析
private static class ShortCache {
static final Short[] cache = new Short[256];
private ShortCache() {
}
static {
for(int i = 0; i < cache.length; ++i) {
cache[i] = new Short((short)(i - 128));
}
}
}
原始类型不能保证线程安全
- 原始数据类型的变量,不能保证线程安全,需要借助AtomicInteger、AtomicLong这样的线程安全类。
|