java 为什么相等运算符适用于整数值直到 128 个数字?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15024933/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 18:15:37  来源:igfitidea点击:

Why equal operator works for Integer value until 128 number?

javaintegerequals-operator

提问by gokhansari

Why Integer "="operator does not work for 128 and after Integer values? Can someone explain this situation?

为什么整数“=”运算符不适用于 128 和整数值之后?有人可以解释这种情况吗?

This is my Java environment: java version "1.6.0_37"

这是我的 Java 环境:java 版本“1.6.0_37”

Java(TM) SE Runtime Environment (build 1.6.0_37-b06)

Java(TM) SE 运行时环境(构建 1.6.0_37-b06)

Java HotSpot(TM) 64-Bit Server VM (build 20.12-b01, mixed mode)

Java HotSpot(TM) 64 位服务器 VM(构建 20.12-b01,混合模式)

Sample Code:

示例代码:

    Integer a;
    Integer b;
    a = 129;
    b = 129;

    for (int i = 0; i < 200; i++) {
        a = i;
        b = i;

        if (a != b) {
            System.out.println("Value:"+ i + " - Different values");
        } else {
            System.out.println("Value"+ i + " Same values");
        }
    }

Some part of console output :

控制台输出的某些部分:

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

Thanks!

谢谢!

采纳答案by lbalazscs

Check out the source code of Integer. You can see the caching of values there.

查看Integer 的源代码。您可以在那里看到值的缓存。

The caching happens only if you use Integer.valueOf(int), not if you use new Integer(int). The autoboxing used by you uses Integer.valueOf

缓存仅在您使用时发生Integer.valueOf(int),如果您使用new Integer(int). 您使用的自动装箱使用Integer.valueOf

According to the JLS, you can always count on the fact that for values between -128 and 127, you get the identical Integer objects after autoboxing, and on some implementations you might get identical objects even for higher values.

根据JLS,您总是可以指望这样一个事实,即对于 -128 和 127 之间的值,自动装箱后您将获得相同的 Integer 对象,并且在某些实现中,即使值更高,您也可能获得相同的对象。

Actually in Java 7 (and I think in newer versions of Java 6), the implementationof the IntegerCache class has changed, and the upper bound is no longer hardcoded, but it is configurable via the property "java.lang.Integer.IntegerCache.high", so if you run your program with the VM parameter -Djava.lang.Integer.IntegerCache.high=1000, you get "Same values" for all values.

实际上在 Java 7 中(我认为在 Java 6 的较新版本中),IntegerCache 类的实现已经改变,上限不再是硬编码的,但它可以通过属性“java.lang.Integer.IntegerCache”进行配置。高”,因此如果您使用 VM 参数运行程序-Djava.lang.Integer.IntegerCache.high=1000,您将获得所有值的“相同值”。

But the JLS still guarantees it only until 127:

但是 JLS 仍然只保证到 127:

Ideally, boxing a given primitive value p, would always yield an identical reference. In practice, this may not be feasible using existing implementation techniques. The rules above are a pragmatic compromise. The final clause above requires that certain common values always be boxed into indistinguishable objects. The implementation may cache these, lazily or eagerly.

For other values, this formulation disallows any assumptions about the identity of the boxed values on the programmer's part. This would allow (but not require) sharing of some or all of these references.

This ensures that in most common cases, the behavior will be the desired one, without imposing an undue performance penalty, especially on small devices. Less memory-limited implementations might, for example, cache all characters and shorts, as well as integers and longs in the range of -32K - +32K.

理想情况下,装箱给定的原始值 p 总是会产生相同的引用。实际上,使用现有的实现技术这可能是不可行的。上述规则是务实的妥协。上面的最后一条要求始终将某些常见值装入无法区分的对象中。实现可能会延迟或急切地缓存这些。

对于其他值,此公式不允许程序员对装箱值的身份进行任何假设。这将允许(但不要求)共享部分或所有这些引用。

这可确保在大多数常见情况下,行为将是所需的行为,而不会造成不应有的性能损失,尤其是在小型设备上。例如,内存限制较少的实现可能会缓存 -32K - +32K 范围内的所有字符和短整数,以及整数和长整数。

回答by Bernhard Barker

Integeris a wrapper class for int.

Integer是 的包装类int

Integer != Integercompares the actual object reference, where int != intwill compare the values.

Integer != Integer比较实际的对象引用, whereint != int将比较值。

As already stated, values -128 to 127 are cached, so the same objects are returned for those.

如前所述,值 -128 到 127 被缓存,因此为它们返回相同的对象。

If outside that range, separate objects will be created so the reference will be different.

如果超出该范围,将创建单独的对象,因此引用将不同。

To fix it:

要解决这个问题:

  • Make the types intor
  • Cast the types to intor
  • Use .equals()
  • 制作类型int
  • 将类型转换为int
  • 利用 .equals()

回答by Denis Rosca

According to Java Language Specifications:

根据 Java 语言规范:

If the value p being boxed is true, false, a byte, a char in the range \u0000 to \u007f, or an int or short number between -128 and 127, then let r1 and r2 be the results of any two boxing conversions of p. It is always the case that r1 == r2.

如果被装箱的值 p 是真、假、一个字节、一个 \u0000 到 \u007f 范围内的字符,或者一个 int 或 -128 到 127 之间的短数,那么让 r1 和 r2 是任何两个装箱转换的结果p. 的 r1 == r2 总是如此。

JLS Boxing Conversions

JLS 拳击转换

Refer to this article for more information on int caching

有关 int 缓存的更多信息,请参阅本文

回答by Christophe Roussy

The Integer object has an internal cache mechanism:

Integer 对象有一个内部缓存机制:

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() {}
}

Also see valueOf method:

另见 valueOf 方法:

public static Integer valueOf(int i) {
    if(i >= -128 && i <= IntegerCache.high)
        return IntegerCache.cache[i + 128];
    else
        return new Integer(i);
}

This is why you should use valueOfinstead of new Integer. Autoboxing uses this cache.

这就是为什么你应该使用valueOf而不是new Integer. 自动装箱使用此缓存。

Also see this post: https://effective-java.com/2010/01/java-performance-tuning-with-maximizing-integer-valueofint/

另见这篇文章:https: //effective-java.com/2010/01/java-performance-tuning-with-maximizing-integer-valueofint/

Using ==is not a good idea, use equals to compare the values.

使用==不是一个好主意,使用等于来比较值。

回答by Doorknob

Use .equals()instead of ==.

使用.equals()代替==

Integer values are only cached for numbers between -127 and 128, because they are used most often.

整数值仅缓存 -127 到 128 之间的数字,因为它们最常用。

if (a.equals(b)) { ... }

回答by Marko Topolnik

Depending on how you get your Integerinstances, it may not work for any value:

根据您获取Integer实例的方式,它可能不适用于任何值:

System.out.println(new Integer(1) == new Integer(1));

prints

印刷

false

This is because the ==operator applied to reference-typed operands has nothing to do with the value those operands represent.

这是因为==应用于引用类型操作数的运算符与这些操作数表示的值无关。

回答by sandrstar

It's because Integerclass implementation logic. It has prepared objects for numbers till 128. You can checkout http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/lang/Integer.javasource of open-jdk for example (search for cache[]).
Basically objects shouldn't be compared using ==at all, with one exception to Enums.

这是因为Integer类的实现逻辑。它已经为数字准备了对象,直到 128。您可以查看 http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/lang/Integer.java源代码-jdk 例如(搜索缓存 [])。
基本上不应该比较使用对象==,枚举除外。