什么';是什么原因导致了这种奇怪的Java行为?

什么';是什么原因导致了这种奇怪的Java行为?,java,jvm,bytecode,Java,Jvm,Bytecode,我想在Longs上测试“==”操作符,我发现如下代码: public static void main(final String[] args) { final Long n = 0L; final Long m = 0L; System.out.println(n + " == " + m + " : " + (n == m)); final Long a = 127L; final Long b = 127L; System.out.prin

我想在
Long
s上测试“==”操作符,我发现如下代码:

public static void main(final String[] args) {
    final Long n = 0L;
    final Long m = 0L;
    System.out.println(n + " == " + m + " : " + (n == m));

    final Long a = 127L;
    final Long b = 127L;
    System.out.println(a + " == " + b + " : " + (a == b));

    final Long A = 128L;
    final Long B = 128L;
    System.out.println(A + " == " + B + " : " + (A == B));

    final Long x = -128L;
    final Long y = -128L;
    System.out.println(x + " == " + y + " : " + (x == y));

    final Long X = -129L;
    final Long Y = -129L;
    System.out.println(X + " == " + Y + " : " + (X == Y));
}
产出:

0 == 0 : true
127 == 127 : true
128 == 128 : false
-128 == -128 : true
-129 == -129 : false
我能想到的唯一解释是,JVM将
[-128127]
中的所有
long
值存储在Perm空间中,并将它们的地址提供给
long
s和上述范围之外的所有内容,它会为代码中遇到的每个静态值创建一个新的分配

我接近正确了吗?在什么情况下,我们必须意识到类似的行为

另外,我知道我应该使用
null
检查然后
.equals()
来比较对象,但我很好奇是否有人知道答案

编辑


jtahlborn的答案是谁给了我关键词自动装箱之后,我发现了这篇关于

的伟大文章,这是自动装箱的结果。请参阅。

-128到+127
将使用
=
运算符计算为true(如果您正在
比较对象引用)。长值(从-128到+127)被放入缓存并多次返回,而较高和较低的数字每次都生成新的长值


这也适用于原始包装类
Integer和Float
。尝试整数和浮点。

Long
有一个内部缓存,用于-128到127之间的值。如果在此间隔内通过
Long.valueOf(Long)
方法或自动装箱创建
Long
,则始终会收到相同对象的相等值。这就是为什么在您的示例中“==”适用于0、127和-128

如果您在[-128127]之外创建
Long
,则始终会在
Long
对象中创建新实例。 这就是为什么“==”不适用于128和-129


查看
Long.valueOf(Long)
源代码。

是的,你是对的。(是的,在这里使用
==
而不是
.equals
是一种罪恶。)您不应该使用空检查。空支票是邪恶的。只是不要使用NULL。我不是downvoter,但我觉得它不需要对-128 t0 127的真实性进行补偿?