Java 为什么相等运算符对整数值起作用直到128个数字?
为什么整数Java 为什么相等运算符对整数值起作用直到128个数字?,java,integer,equals-operator,Java,Integer,Equals Operator,为什么整数==运算符不适用于128和之后的整数值?有人能解释一下这种情况吗 这是我的Java环境: java版本“1.6.0_37” Java(TM)SE运行时环境(build 1.6.0_37-b06) Java HotSpot(TM)64位服务器虚拟机(构建20.12-b01,混合模式) 示例代码: 整数a; 整数b; a=129; b=129; 对于(int i=0;i
==
运算符不适用于128和之后的整数值?有人能解释一下这种情况吗
这是我的Java环境:
java版本“1.6.0_37”
Java(TM)SE运行时环境(build 1.6.0_37-b06)
Java HotSpot(TM)64位服务器虚拟机(构建20.12-b01,混合模式)
示例代码:
整数a;
整数b;
a=129;
b=129;
对于(int i=0;i<200;i++){
a=i;
b=i;
如果(a!=b){
System.out.println(“值:“+i+”-不同的值”);
}否则{
System.out.println(“值:“+i+”-相同值”);
}
}
控制台输出的某些部分:
Value:124 - Same values
Value:125 - Same values
Value:126 - Same values
Value:127 - Same values
Value:128 - Different values
Value:129 - Different values
Value:130 - Different values
Value:131 - Different values
Value:132 - Different values
根据Java语言规范: 如果要装箱的值p为true、false、一个字节、一个字符,范围为 \u0000到\u007f,或介于-128和127之间的整数或短数,然后 设r1和r2是p的任意两个装箱转换的结果。它是 始终是r1==r2的情况 使用
.equals()
而不是=
整数值只缓存在-127和128之间的数字中,因为它们是最常用的
if (a.equals(b)) { ... }
退房。您可以在那里看到值的缓存
只有在使用Integer.valueOf(int)
时,才会发生缓存,而在使用newinteger(int)
时不会发生缓存。您使用的自动装箱使用Integer.valueOf
根据,对于-128和127之间的值,在自动装箱后可以得到相同的整数对象,在某些实现中,甚至对于更高的值,也可以得到相同的对象
实际上,在Java 7中(我认为在Java 6的较新版本中),IntegerCache类的定义已经改变,上限不再是硬编码的,但它可以通过属性“Java.lang.Integer.IntegerCache.high”进行配置,因此如果您使用VM参数-Djava.lang.Integer.IntegerCache.high=1000
运行程序,您会得到“相同值”适用于所有值
但JLS仍仅在以下情况下提供担保:
理想情况下,装箱一个给定的原语值p总是会产生一个相同的引用。实际上,使用现有的实现技术,这可能是不可行的。上面的规则是一种实用的折衷。上面的最后一句要求某些公共值总是装箱到不可区分的对象中。实现可能会缓存这些人,懒洋洋地或急切地
对于其他值,此公式不允许程序员对装箱值的标识进行任何假设。这将允许(但不要求)共享部分或所有这些引用
这可以确保在大多数常见情况下,行为都是所需的,不会造成不适当的性能损失,尤其是在小型设备上。内存限制较少的实现可能会缓存-32K-+32K范围内的所有字符和短字符以及整数和长字符
Integer
是int
的包装类
Integer!=Integer
比较实际对象引用,其中int!=int
将比较值
如前所述,缓存值-128到127,因此为这些值返回相同的对象
如果超出该范围,将创建单独的对象,因此引用将不同
要解决此问题,请执行以下操作:
- 使类型
或int
- 将类型强制转换为
或int
- 使用
.equals()
private static class IntegerCache {
static final int high;
static final Integer cache[];
static {
final int low = -128;
// high value may be configured by property
int h = 127;
if (integerCacheHighPropValue != null) {
// Use Long.decode here to avoid invoking methods that
// require Integer's autoboxing cache to be initialized
int i = Long.decode(integerCacheHighPropValue).intValue();
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - -low);
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
}
private IntegerCache() {}
}
私有静态类整型缓存{
静态最终int高;
静态最终整数缓存[];
静止的{
最终整数下限=-128;
//高值可由属性配置
int h=127;
if(integerCacheHighPropValue!=null){
//在此处使用Long.decode以避免调用
//需要初始化Integer的自动装箱缓存
int i=Long.decode(integerCacheHighPropValue).intValue();
i=数学最大值(i,127);
//最大数组大小为整数。最大值为
h=数学最小值(i,整数最大值--low);
}
高=h;
缓存=新整数[(高-低)+1];
int j=低;
for(int k=0;k
另请参见方法的价值:
public static Integer valueOf(int i) {
if(i >= -128 && i <= IntegerCache.high)
return IntegerCache.cache[i + 128];
else
return new Integer(i);
}
公共静态整数值(int i){
如果(i>=-128&&i这是因为Integer
类实现逻辑。它为数字准备了对象,直到128。例如,您可以签出开放jdk的源代码(搜索缓存[])。
基本上,不应该使用==
来比较对象,枚举除外。根据获取整型
实例的方式,它可能不适用于任何值:
System.out.println(new Integer(1) == new Integer(1));
印刷品
false
这是因为应用于引用类型操作数的=
运算符与这些操作数表示的值无关。这个答案是错误的,它与热点jvm无关,缓存是在Integer的源代码@lbalazscs中实现的,据我所知,缓存的值依赖于jvm。我认为java语言规范中指定了此缓存,但未指定要缓存的值。这就是我提到hotspot jvm的原因。这不正确吗?这不正确。例如,为什么不看一下java.lang.Integer
的源代码。不正确,它与java.lang.Integer的实现有关文档Integer.valueOf(而不是JLS)的umentation提到此方法可以使用缓存。