0x00
前段时间校稿的时候看到一道有意思的题目
package com.javapapers.java;
public class JavaIntegerCache {
public static void main(String... strings) {
Integer integer1 = 3;
Integer integer2 = 3;
//Integer integer1 = new Integer(3);
//Integer integer2 = new Integer(3);
if (integer1 == integer2)
System.out.println("integer1 == integer2");
else
System.out.println("integer1 != integer2");
Integer integer3 = 300;
Integer integer4 = 300;
if (integer3 == integer4)
System.out.println("integer3 == integer4");
else
System.out.println("integer3 != integer4");
}
}
我知道它们会不相等,因为两个都是对象,对象用 == 比较的实际上是内存地址,那结果都一样的话写出来就没有意思了。肯定是有一个相等一个不相等。
来公布下结果:
integer1 == integer2
//integer1 != integer2
integer3 != integer4
为什么呢?
因为缓存!
在 Java 5 版本中为了提升性能引入了一个特性,就是会自动缓存 -128~127 的整数。就拿上面的示例代码来说,对象 integer1 和 integer2 实际上是同一个对象,在内存中的位置相同。
注意注意!!!
缓存 Integer 对象有个重要的前提条件就是:自动装箱的对象才会缓存!(原始类型和封装类型的自动装箱、拆箱就不再详细介绍了)
如果把上面的代码改改就是另外的结果了!
Integer integer1 = new Integer(3);
Integer integer2 = new Integer(3);
这种情况是不会缓存哒!记住咯!
为什么是这个范围的数呢?
因为这个范围的数使用的最多。
这个范围能改吗?
可以,VM arguments 设置参数 -XX:AutoBoxCacheMax=size 就能修改这个值的范围。-128~size
其他类型自动装箱的时候也会缓存么?
会的,Byte、Short、Long 有固定范围: -128 ~ 127。对于 Character: 范围是 0 到 127。(通过参数修改范围只对 Integer 有效)
0x01
到这里还没有完!因为我联想到了 String 的常量池。
面试的时候经常会碰到像下面这样的题目。
String a = new String("a");
String b = "a";
String c = "a";
//注意是 == ,不是比较对象的字面值哦
System.out.println(a == b);
System.out.println(b == c);
求输出结果。
false
true
如果按照上面缓存整数的方式思考的话,估计也能猜得到答案。
new 出来的对象 a 和直接赋值的对象 b 是不相等的,虽然值一样。
但是同样两个都是直接赋值创建的对象 b、c 会相等。
直接字面值创建的 String 对象会先在常量池中查找是否已经存在,如果存在则直接返回该引用,没有就加入到常量池中。
new 创建的对象和常量池无关。无论常量池中是否已经存在,都会创建新对象。
intern 方法会先去常量池查找,找到了就返回,找不到就加进常量池再返回。
a.intern() == b 为 true
不知道 Java 中还有哪些类似的缓存策略。
There are no comments on this post.