1等于128吗?一段有意思代码学习Integer 享元模式

1等于128吗?一段有意思代码学习Integer 享元模式关于 Integer 作为 int 包装类 新手经常会犯的错误是 比较两个 Integer 用 作为有经验的开发我们知道 包装类 String 都应用用 equals 方法进行判断

大家好,欢迎来到IT知识分享网。

关于Integer ,作为int 包装类,新手经常会犯的错误是,比较两个Integer 用 ==,作为有经验的开发我们知道,包装类、String 都应用用equals方法进行判断。

在实际项目中,我们经常会有枚举值定义成Integer类型,有相当部分同学不注意,使用== 进行了比较,但是似乎又也没怎么出现Bug。这就不得不提起 Integer内部类 IntegerCache,它缓存了[-128,127] 的对象,这里使用了享元模式,避免了对象的重复创建。

因为枚举值数量通常比较小,在[-128,127] 之间,代码中也没有谁变态到 new Integer(value),所以,许多场景使用的是 IntegerCache 缓存的对象,所以== 没出现了问题。但不能说这么用没有错,程序员要严谨,以防后续用到数值超过缓存的范围,且不排除谁用new Integer 创建对象。

虽然IntegerCache 不对外暴露,但是Java反射,可是神通广大,如果用反射把一些缓存的值改掉,就会产生“有意思的”结果。下面代码大家觉得输出什么

 Integer one = Integer.valueOf(1); Class iClass = Integer.class; Field valueField = iClass.getDeclaredField("value"); valueField.setAccessible(true); valueField.set(one,128); System.out.println((Integer)1 == 128);
1等于128吗?一段有意思代码学习Integer 享元模式

输出true

其实这个涉及知识点不少,涉及Java 自动拆箱、Integer缓存

左边包装类 右边基本类型,会把左边拆卸为基本类型,由于它的value 已经被改为128了,所以输出true .

但是上述代码稍微修改下, 改为 Integer(1) == (Integer)128

 Integer one = Integer.valueOf(1); Class iClass = Integer.class; Field valueField = iClass.getDeclaredField("value"); valueField.setAccessible(true); valueField.set(one,128); System.out.println((Integer)1 == (Integer)128);
1等于128吗?一段有意思代码学习Integer 享元模式

结果就为false。

因为上面代码两个Integer 类型,比较是不是同一个对象,显然128不在缓存中,

如果把128 改为缓存范围内一个数呢,如下,结果也会为false。

 public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException { Integer one = Integer.valueOf(1); Class iClass = Integer.class; Field valueField = iClass.getDeclaredField("value"); valueField.setAccessible(true); valueField.set(one,3); System.out.println((Integer)1 == (Integer)3); }
1等于128吗?一段有意思代码学习Integer 享元模式

学C++的,估计第一次接触这个要吐血了,既然说了顺便复习下Integer 类型值默认null ,int 默认值0。这个IntgerCache 确实饶了点。

同样的Long 也有类似的Cache,值得一提的是redis 中有类似的缓存,只是范围不一样,编程复杂度与空间开销方面,如果是我会选择简单,期待jdk某个版本会把它干掉。

讲完,后面持续输出

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/92896.html

(0)

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信