IntegerCache

先看一段代码

Integer int1 = 100;
Integer int2 = 100;
Integer int3 = 500;
Integer int4 = 500;
System.out.println(int1 == int2);
System.out.println(int3 == int4);

执行一下:

true
false

和大多数人心里想的不一样吧,到底是全是true还是全是false呀。
然而一个是true,一个是false,这是为什么呢?

根据Java编译机制,.java文件在编译以后会生成.class文件给JVM加载执行,于是找到.class文件,反编译看了一下,发现编译器在编译我们的代码时,在我们声明的变量加上了valueOf方法 ,代码变成了如下:

Integer int1 = Integer.valueOf(100);
Integer int2 = Integer.valueOf(100);
Integer int3 = Integer.valueOf(500);
Integer int4 = Integer.valueOf(500);
System.out.println(int1 == int2);
System.out.println(int3 == int4);

看一下valueOf方法的实现

我们发现,Integer的作者在写这个类时,为了避免重复创建对象,对Integer值做了缓存,如果这个值在缓存范围内,直接返回缓存好的对象,否则new一个新的对象返回,那究竟这个缓存到底缓存了哪些内容呢?看一下IntegerCache这个类:

这是一个内部静态类,该类只能在Integer这个类的内部访问,这个类在初始化的时候,会去加载JVM的配置,如果有值,就用配置的值初始化缓存数组,否则就缓存 -128到127之间的值。
再来看看我们之前的代码:

结论:我们在比较两个Integer对象的值时,无论是怎么声明的,都一定要使用equals去比较,不能用==,==是判断两个对象是否为同一个对象,而equals才是判断两个对象值是否相同(在该类重写了equals方法的时候,如果不重写则默认使用继承自Object类的equals方法,该方法通过计算两个对象的内存地址的hash值然后比较两个hash值是否相等,其实还是在比较是否为同一个对象)在Java中没有重载操作符这一说,特别是从其它语言转到Java的童鞋们要注意。

思考以下代码的执行结果:

Integer int1 = new Integer(100);
Integer int2 = new Integer(100);
System.out.println(int1 == int2);

由于创建了两个不同的Integer对象,因此通过<mark>判断会打印false,Integer是引用类型,不要用</mark>判断,==判断的是两个对象是否为同一个对象,要判断其值是否相同要用equals

全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务