A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© ﹎◇waiting﹎ 初级黑马   /  2012-8-1 13:23  /  2252 人查看  /  3 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

今天上午问我一些关于java”==“的问题他给我发了以下问题,
以下java小程序到底是等于,还是不等于?


    代码片段1
  
Java代码
public static void main(final String[] args) {
     Integer a = new Integer(100);
     Integer b = 100;
     System.out.println(a == b);  
}
  
  
  这段代码的输出是什么?相信很多人都会很容易的猜到:false,因为a、b两个对象的地址不同,用“==”比较时是false。恭喜你,答对了。
  
  
  
再看下面的一段代码:
  
  
  
    代码片段2
  
Java代码
public static void main(final String[] args) {
     Integer a = 100;
     Integer b = 100;
     System.out.println(a == b);  
}
  
  
你可能会回答,这没什么不一样啊,所以还是false。很遗憾,如果你执行上面的一段代码,结果是true。
  
  
  
上面的代码可能让你有些意外,那好吧,再看看下面的这段代码:
  
  
  
     代码片段3
  
Java代码
public static void main(final String[] args) {
     Integer a = 156;
     Integer b = 156;
     System.out.println(a == b);  
}
  结果是true吗?很遗憾,如果你执行上面的一段代码,结果是false。
  
  
  
  感到吃惊吗?那最后再看下面的一段代码:
  
  
  
     代码片段4
  
Java代码
public static void main(final String[] args) {
     Integer a = Integer.valueOf(100);
     Integer b = 100;
     System.out.println(a == b);  
}
最后的结果,可能你已经猜到了,是true。

为什么会出现这样的答案啊?

3 个回复

倒序浏览
本帖最后由 尤洋 于 2012-8-1 16:31 编辑

这问题我在13版中就回答了
问题核心在于比较类里面的数值是否相等时,用equals()方法
测试两个包装类的引用是否指向同一个对象时,用==,
而你的问题中还隐藏了另外一个因素作为干扰,就是integer的范围问题,所以不容易分辨
     其实按照控制变量法的思想 找每两段代码的不同点,你自己就能分析出他的答案。

代码片段1 是false 因为new了新的对象
代码片段2 java为了提高效率,初始化了-128--127之间的整数对象,所以在赋值在这个范围内都是同一个对象。引用是指向同一个对象 自然是true。
代码片段3看起来和2一样,为什么是false呢,原因在于数值150超出了[-128,127]的区间范围了,所以是false
代码片段4 最简单,其实他与代码片段2的写法等效。相当于代码2中interer a=100 在编译后的情况
回复 使用道具 举报
1、Integer类的内部, 有一个常量静态数组, 在Integer类被加载的时候, 预先创建了-128 ~ 127的Integer对象, 所以当声明的Integer类型变量的值在-128 ~ 127的范围内时, 不会新创建对象, 直接引用数组中创建好的.
2、int是一个基本数据类型,不存在integer那样的创建对象的过程,只要数值不超过-2^31~2^31-1(对于32位的编译器来说),编译器就不会报错
3、“==”对于基本数据类型,比较的是值,对于引用数据类型,比较的是对象的地址值。equals比较的是对象的值是否相等。

                                                                                                                              一、
class  Testa
{
public static void main(String[] args)
{
  Integer a=new Integer(100);//新建了一个对象,值为100,并将对象的引用地址值赋给a
  Integer b=100;//在堆中创建一个对象,存值为100,并将地址值赋给b
  System.out.println(a==b);
}
}

对象不同,故地址值不同,所以结果为false(如图Testa)


                                                                                                                          二、

class  Testb
{
public static void main(String[] args)
{
  Integer a=100;//在堆中创建一个对象,存值为100,并将地址值赋给a
  Integer b=100;//100的值没有超过-128~127,直接引用已经创建好的对象
  System.out.println(a==b);
}
}



对象一样,故地址值相同,所以结果为true(如同Testb)


                                                                                                                 三、
class  Testc
{
public static void main(String[] args)
{
  Integer a=156;//在堆中创建一个对象,存值为156,并将地址值赋给a
  Integer b=156;//156的值已超过-128~127,会重新创建新的对象值为156,并将地址值赋给b
  System.out.println(a==b);
}
}


对象不同,故地址之不同,所以结果为false(如同Testc)

                                                                                                         
                                                                                                                      四、
class  Testd
{
public static void main(String[] args)
{
  Integer a=Integer.valueOf(100);//通过valueof(100)方法,获取的是已有对象的值,再将地址值赋给a
  Integer b=100;
  System.out.println(a==b);
}
}

对象一样,故地址值相同,所以结果为true(如同Testd)




更多图片 小图 大图
组图打开中,请稍候......
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马