2012-11-20 92 views
1

可能重复:
Weird Java Boxing为什么第一个if case打印等于和第二个不等于?

public class example { 
    public static void main(String[] args) { 

     Integer a=127,b=127; 
     if(a==b) 
      System.out.println("Equal"); 
     else 
      System.out.println("Not Equal"); 
     Integer c=128,d=128; 
     if(c==d) 
      System.out.println("Equal"); 
     else 
      System.out.println("Not Equal"); 
    } 

} 

输出:

Equal 
Not Equal 
+5

的源代码,他们又来了!它已被问很多次了... – Burkhard

+0

用以下选项之一试用它:'-Djava.lang.Integer.IntegerCache.high = 128'或'-XX:AutoBoxCacheMax = 128'或 '-XX:+ AggressiveOpts ' –

回答

5

基本上整数-127和127之间,以这样的方式 '缓存',当你使用这些数字你总是指的是相同的号码 内存,这就是为什么你的==的作品。

该范围之外的任何整数都不会被缓存,因此引用 不相同。

因此,当你试图比较127与127有只取得了一个对象 和它的工作的权利,但是当你用128试过出来的 的范围内,它创建了两个对象,所以你不能用它们进行比较 ==运算符。

为此使用.equals()(比较对象引用)method.Please指 this了解更多详情。

Integer c=128,d=128; 
if(c.equals(d)) 
     System.out.println("Equal"); 
    else 
     System.out.println("Not Equal"); 
+1

[语言规格](http://java.sun.com/docs/books/jls/third_edition/html/conversions.html#5.1.7)要求在-128(不包括-127)范围内自动填写整数,通过+127被缓存。一个实现也可以自由缓存其他值(在这种情况下+128也可能打印了“Equals”)。 –

+1

@TedHopp你知道他们为什么必须被缓存吗? –

+0

@JanDvorak - 它是Java语言规范所要求的。从[JLS第5.1.7节](http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.7):_“如果值为p盒装是真的,假的,一个字节或范围在\ u0000到\ u00f之间的字符,或者在-128到127之间的一个int或短数字,然后让r1和r2成为任何两次装箱转换的结果p。r1 == r2始终是这种情况。“_请参阅链接了解为什么这样做的理由。 –

0

这是因为在范围内Integer号码[-128,127]被存储在堆。因此,当你比较对象引用而不是对象值,并且Integer a = 127Integer b = 127指向堆中的同一对象时,表达式的求值为true

Integer值超出这个范围,你会得到两个不同的对象,所以参考比较返回false

+1

从技术上讲,它们存储在一个静态数组中,而不是堆(数据结构;它们存储在_the_堆(内存区域),虽然) –

0

从Integer.java

private static class IntegerCache { 

private IntegerCache(){} 

static final Integer cache[] = new Integer[-(-128) + 127 + 1]; 

static { 
    for(int i = 0; i < cache.length; i++) 
    cache[i] = new Integer(i - 128); 
} 
} 

/** 
* Returns a <tt>Integer</tt> instance representing the specified 
* <tt>int</tt> value. 
* If a new <tt>Integer</tt> instance is not required, this method 
* should generally be used in preference to the constructor 
* {@link #Integer(int)}, as this method is likely to yield 
* significantly better space and time performance by caching 
* frequently requested values. 
* 
* @param i an <code>int</code> value. 
* @return a <tt>Integer</tt> instance representing <tt>i</tt>. 
* @since 1.5 
*/ 
public static Integer valueOf(int i) { 
final int offset = 128; 
if (i >= -128 && i <= 127) { // must cache 
    return IntegerCache.cache[i + offset]; 
} 
    return new Integer(i); 
} 
相关问题