为什么在Java中比较整数包装时128==128为false,而127==127为true?

为什么在Java中比较整数包装时128==128为false,而127==127为true?,java,integer,comparison,pass-by-reference,pass-by-value,Java,Integer,Comparison,Pass By Reference,Pass By Value,输出: class D { public static void main(String args[]) { Integer b2=128; Integer b3=128; System.out.println(b2==b3); } } class D { public static void main(String args[]) { Integer b2=127; Integer b3=

输出:

class D {
    public static void main(String args[]) {
        Integer b2=128;
        Integer b3=128;
        System.out.println(b2==b3);
    }
}
class D {
    public static void main(String args[]) {
        Integer b2=127;
        Integer b3=127;
        System.out.println(b2==b3);
    }
}

输出:

class D {
    public static void main(String args[]) {
        Integer b2=128;
        Integer b3=128;
        System.out.println(b2==b3);
    }
}
class D {
    public static void main(String args[]) {
        Integer b2=127;
        Integer b3=127;
        System.out.println(b2==b3);
    }
}

注意:介于-128和127之间的数字为真。

自动装箱缓存-128到127。这在JLS()中指定

如果要装箱的值p为true、false、一个字节、一个\u0000到\u007f范围内的字符,或一个介于-128和-128之间的整数或短数字 127,然后让r1和r2是任意两个装箱转换的结果 p。r1==r2总是这样


处理对象时要记住的一个简单规则是-使用
.equals
如果要检查两个对象是否“相等”,请在查看它们是否指向同一实例时使用
=

自动装箱缓存-128到127。这在JLS()中指定

如果要装箱的值p为true、false、一个字节、一个\u0000到\u007f范围内的字符,或一个介于-128和-128之间的整数或短数字 127,然后让r1和r2是任意两个装箱转换的结果 p。r1==r2总是这样


处理对象时要记住的一个简单规则是-使用
.equals
如果要检查两个对象是否“相等”,请在查看它们是否指向同一实例时使用
=

在Java中编译数字文本并将其分配给整数(大写
I
)时,编译器会发出:

true
使用自动装箱时也会生成这行代码

valueOf
的实现使得某些数字被“池化”,并且对于小于128的值,它返回相同的实例

java 1.6源代码第621行:

Integer b2 =Integer.valueOf(127)
公共静态整数值(int i){

如果(i>=-128&&i在Java中编译数字文本并将其分配给整数(大写
i
)时,编译器会发出:

true
使用自动装箱时也会生成这行代码

valueOf
的实现使得某些数字被“池化”,并且对于小于128的值,它返回相同的实例

java 1.6源代码第621行:

Integer b2 =Integer.valueOf(127)
公共静态整数值(int i){

如果(i>=-128&&i使用原语数据类型int在这两种情况下都会产生true,则为预期输出

但是,由于您使用的是整数对象,==运算符具有不同的含义

在对象的上下文中,==检查变量是否引用相同的对象引用

要比较对象的值,应使用equals()方法 例如


这将指示b2是否小于b1、大于或等于(有关详细信息,请查看API)

在这两种情况下,使用基本数据类型ints都将生成true,即预期输出

但是,由于您使用的是整数对象,==运算符具有不同的含义

在对象的上下文中,==检查变量是否引用相同的对象引用

要比较对象的值,应使用equals()方法 例如


这将指示b2是否小于b1、大于或等于(有关详细信息,请查看API)

我写了以下内容,因为这个问题不仅仅针对Integer。我的结论是,如果不正确使用API,通常会看到不正确的行为。正确使用它,应该会看到正确的行为:

 b2.equals(b1)

我写了以下内容,因为这个问题不仅仅局限于Integer。我的结论是,如果不正确地使用API,通常会看到不正确的行为。正确地使用它,您应该会看到正确的行为:

 b2.equals(b1)

看看Integer.java,如果值介于-128和127之间,它将使用缓存池,因此
(Integer)1==(Integer)1
(Integer)222!=(Integer)222

public static void main (String[] args) {
    Byte b1=127;
    Byte b2=127;

    Short s1=127; //incorrect should use Byte
    Short s2=127; //incorrect should use Byte
    Short s3=128;
    Short s4=128;

    Integer i1=127; //incorrect should use Byte
    Integer i2=127; //incorrect should use Byte
    Integer i3=128;
    Integer i4=128;

    Integer i5=32767; //incorrect should use Short
    Integer i6=32767; //incorrect should use Short

    Long l1=127L;           //incorrect should use Byte
    Long l2=127L;           //incorrect should use Byte
    Long l3=13267L;         //incorrect should use Short
    Long l4=32767L;         //incorrect should use Short
    Long l5=2147483647L;    //incorrect should use Integer 
    Long l6=2147483647L;    //incorrect should use Integer
    Long l7=2147483648L;
    Long l8=2147483648L;

    System.out.print(b1==b2); //true  (incorrect) Used API correctly
    System.out.print(s1==s2); //true  (incorrect) Used API incorrectly
    System.out.print(i1==i2); //true  (incorrect) Used API incorrectly
    System.out.print(l1==l2); //true  (incorrect) Used API incorrectly

    System.out.print(s3==s4); //false (correct) Used API correctly
    System.out.print(i3==i4); //false (correct) Used API correctly
    System.out.print(i5==i6); //false (correct) Used API correctly
    System.out.print(l3==l4); //false (correct) Used API correctly
    System.out.print(l7==l8); //false (correct) Used API correctly
    System.out.print(l5==l6); //false (correct) Used API incorrectly

}
/**
*返回一个{@code Integer}实例,该实例表示指定的
*{@code int}值。如果新的{@code Integer}实例不是
*如果需要,通常应优先使用该方法
*构造函数{@link#Integer(int)},因为这种方法很可能
*通过
*缓存频繁请求的值。
*
*此方法将始终缓存范围为-128到127的值,
*包含,并且可能缓存此范围之外的其他值。
*
*@param i是一个{@code int}值。
*@返回表示{@code i}的{@code Integer}实例。
*@自1.5
*/
公共静态整数值(int i){
断言IntegerCache.high>=127;

如果(i>=IntegerCache.low&&i查看Integer.java,如果值介于-128和127之间,它将使用缓存池,因此
(Integer)1==(Integer)1
(Integer)222!=(Integer)222

public static void main (String[] args) {
    Byte b1=127;
    Byte b2=127;

    Short s1=127; //incorrect should use Byte
    Short s2=127; //incorrect should use Byte
    Short s3=128;
    Short s4=128;

    Integer i1=127; //incorrect should use Byte
    Integer i2=127; //incorrect should use Byte
    Integer i3=128;
    Integer i4=128;

    Integer i5=32767; //incorrect should use Short
    Integer i6=32767; //incorrect should use Short

    Long l1=127L;           //incorrect should use Byte
    Long l2=127L;           //incorrect should use Byte
    Long l3=13267L;         //incorrect should use Short
    Long l4=32767L;         //incorrect should use Short
    Long l5=2147483647L;    //incorrect should use Integer 
    Long l6=2147483647L;    //incorrect should use Integer
    Long l7=2147483648L;
    Long l8=2147483648L;

    System.out.print(b1==b2); //true  (incorrect) Used API correctly
    System.out.print(s1==s2); //true  (incorrect) Used API incorrectly
    System.out.print(i1==i2); //true  (incorrect) Used API incorrectly
    System.out.print(l1==l2); //true  (incorrect) Used API incorrectly

    System.out.print(s3==s4); //false (correct) Used API correctly
    System.out.print(i3==i4); //false (correct) Used API correctly
    System.out.print(i5==i6); //false (correct) Used API correctly
    System.out.print(l3==l4); //false (correct) Used API correctly
    System.out.print(l7==l8); //false (correct) Used API correctly
    System.out.print(l5==l6); //false (correct) Used API incorrectly

}
/**
*返回一个{@code Integer}实例,该实例表示指定的
*{@code int}值。如果新的{@code Integer}实例不是
*如果需要,通常应优先使用该方法
*构造函数{@link#Integer(int)},因为这种方法很可能
*通过
*缓存频繁请求的值。
*
*此方法将始终缓存范围为-128到127的值,
*包含,并且可能缓存此范围之外的其他值。
*
*@param i是一个{@code int}值。
*@返回表示{@code i}的{@code Integer}实例。
*@自1.5
*/
公共静态整数值(int i){
断言IntegerCache.high>=127;

如果(i>=IntegerCache.low&&i,则是与Java相关的内存优化

为了节省内存,Java“重用”了其值为 属于以下范围:

所有布尔值(true和false)

所有字节值

从\u0000到\u007f的所有字符值(即十进制中的0到127)

从-128到127的所有短值和整数值


它是与Java相关的内存优化

为了节省内存,Java“重用”了其值为