Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/392.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么相等运算符对整数值起作用直到128个数字?_Java_Integer_Equals Operator - Fatal编程技术网

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提到此方法可以使用缓存。