黑马程序员技术交流社区

标题: 【经典】 高分悬赏 , 不服来战 ! [打印本页]

作者: 不落羽    时间: 2016-3-14 18:53
标题: 【经典】 高分悬赏 , 不服来战 !
一、==符的使用
首先看一段比较有意思的代码
  1. Integer a = 1000,b=1000;
  2. Integer c = 100,d=100;    public void mRun(final String name){
  3.         new Runnable() {
  4.             
  5.             public void run() {
  6.                 System.out.println(name);
  7.             }
  8.         };
  9.     }
  10.    

  11. System.out.println(a==b);
  12. System.out.println(c==d);
复制代码

如果这道题你能得出正确答案,并能了解其中的原理的话。说明你基础还可以。如果你的答案 是 true 和true的话,你的基础就有所欠缺了。


二、String

接着看代码
  1. String s1 = "abc";
  2.                 String s2 = "abc";
  3.                 String s3 = new String("abc");
  4.                 System.out.println(s1 == s2);
  5.                 System.out.println(s1 == s3);
复制代码



三、final关键字
还是来看一段代码
  1. public void mRun(final String name){
  2.                 new Runnable() {
  3.                        
  4.                         public void run() {
  5.                             try {
  6.                               Thread.sleep(1000);
  7.                            } catch (InterruptedException e) {
  8.                              // TODO Auto-generated catch block
  9.                             e.printStackTrace();
  10.                            }  
  11.                            System.out.println(name);
  12.                         }
  13.                 }.start();
  14.         }
复制代码

当内部类访问局部变量的时候,需要在局部变量前加final修饰符,不然编译器就会报错。
通常我们也是这么干的。好的,第二个问题来了,为什么要加final修饰符?

四、Integer与int那些事
看下面代码
  1.    Integer a = new Integer(1000);
  2.                 int b = 1000;
  3.                 Integer c = new Integer(10);
  4.                 Integer d = new Integer(10);
  5.                 System.out.println(a == b);
  6.                 System.out.println(c == d);
复制代码

这道题是继第一题的后续,如果这道题你能很快速的得出答案,那么恭喜你,==比较符你就算掌握的比较透彻了。


【注:  2 天时间 ,  最快正确回答全部问题的同學获得悬赏奖励  , 到时候会公布正确答案 , 答不出来的朋友也别灰心 , 就当学习了  ^_^  】



作者: 年强    时间: 2016-3-14 20:46
简单啊。。。。。。。。
作者: 叫我高祥小朋友    时间: 2016-3-14 23:46
==比较的是地址值
final修饰的变量会变为常量只能赋值一次
作者: xgm    时间: 2016-3-15 00:38
  1. public static Integer valueOf(int i) {  
  2.         if(i >= -128 && i <= IntegerCache.high)  
  3.                 return IntegerCache.cache[i + 128];  
  4.         else  
  5.                 return new Integer(i);  
  6. }
复制代码
我们用Integer a = 数字;来赋值的时候Integer这个类是调用的public static Integer valueOf(int i)这个方法。当数组在-127到128之间,直接返回int原始数据类型,否则直接new一个对象出来,而==比较的是内存地址     因此
基本类型与对象比较的时候,对象会自动拆箱变成基本类型的值在进行比较,所以比较的是里面的值 因此
   Integer a = new Integer(1000);               
  int b = 1000;            
  Integer c = new Integer(10);               
  Integer d = new Integer(10);               
  System.out.println(a == b);  true               
  System.out.println(c == d);  false  ==是比较内存空间



关于String   http://bbs.itheima.com/thread-281878-1-1.html   这是我之前写得帖子里面有内存模型。


至于当内部类访问局部变量的时候,需要在局部变量前加final修饰符,不然编译器就会报错


http://bbs.itheima.com/thread-204868-1-1.html 这是我在黑马论坛看到的一个帖子我觉得总结的挺好



作者: xiaobinghe    时间: 2016-3-15 00:44
一:false;true;
二:true;false;
三:延长局部变量的寿命;如果没有final修饰,局部变量就会随着方法的调用而存在,随着方法的弹栈而消失;用final修饰的变量就变成了常量,在运行中会进方法区的常量池;即使方法弹栈了,对象还在,如果我们还要用它,就可以通过对象再调用到它.PS:不过在jdk1.8中可以不用final修饰也可以用了.
四:false,false
作者: yuluoyu    时间: 2016-3-16 00:19
heheda!!!!!!
作者: superlu    时间: 2016-3-16 17:56
好难啊看着
作者: ck1993    时间: 2016-3-16 18:18
貌似已经被解决了,我刚学到这里,还好看的懂!
作者: lkm1916    时间: 2016-3-16 22:28
66666666666666
作者: MuziTian    时间: 2016-3-16 22:31
6666666666666
作者: 不落羽    时间: 2016-3-17 15:51
xgm 发表于 2016-3-15 00:38
我们用Integer a = 数字;来赋值的时候Integer这个类是调用的public static Integer valueOf(int i)这个方 ...

小伙子还是很不错的 :

公布下答案 1 , 运行代码,我们会得到 false  true。我们知道==比较的是两个对象的引用,这里的abcd都是新建出来的对象,按理说都应该输入false才对。这就是这道题的有趣之处,无论是面 试题还是论坛讨论区,这道题的出场率都很高。原理其实很简单,我们去看下Integer.java这个类就了然了。
  public static Integer valueOf(int i) {
        return  i >= 128 || i < -128 ? new Integer(i) : SMALL_VALUES[i + 128];
    }

    /**
     * A cache of instances used by {@link Integer#valueOf(int)} and auto-boxing
     */
    private static final Integer[] SMALL_VALUES = new Integer[256];

    static {
        for (int i = -128; i < 128; i++) {
            SMALL_VALUES[i + 128] = new Integer(i);
        }
    }


      当我们声明一个Integer c = 100;的时候。此时会进行自动装箱操作,简单点说,也就是把基本数据类型转换成Integer对象,而转换成Integer对象正是调用的 valueOf方法,可以看到,Integer中把-128-127 缓存了下来。官方解释是小的数字使用的频率比较高,所以为了优化性能,把这之间的数缓存了下来。这就是为什么这道题的答案回事false和ture了。当 声明的Integer对象的值在-128-127之间的时候,引用的是同一个对象,所以结果是true


答案  3:

         


      这种代码相信大家写过很多,当内部类访问局部变量的时候,需要在局部变量前加final修饰符,不然编译器就会报错。通常我们也是这么干的。好的,第二个 问题来了,为什么要加final修饰符?相信大多数小伙伴都没有思考过这个问题,但凡使用的时候,直接加上就得了,从来没去深究过其中的原理。这对于一个 优秀的程序员来说是不可取,我们不仅要知其然还要知其所以然。      现在我们来分析一下,为什么要加final关键字。首先内部类的生命周期是成员级别的,而局部变量的生命周期实在方法体之类。也就是说会出现这样一种情 况,当mRun方法执行,new 的线程运行,新线程里面会睡一秒。主线程会继续执行,mRun执行完毕,name属性生命周期结束。1秒之 后,Syetem.out.printh(name)执行。然而此时name已经寿终正寝,不在内存中了。Java就是为了杜绝这种错误,严格要求内部类 中方位局部变量,必须使用final关键字修饰。局部变量被final修饰之后,此时会在内存中保有一份局部变得的复制品,当内部类访问的时候其实访问的 是这个复制品。这就好像是把局部变量的生命周期变长了。说到底还是Java工程师提前把这个坑给我们填了,不然不知道又会有多少小伙伴会为了内部类局部变 量而发愁了。



作者: xgm    时间: 2016-3-17 15:54
不落羽 发表于 2016-3-17 15:51
小伙子还是很不错的 :

公布下答案 1 , 运行代码,我们会得到 false  true。我们知道==比较的是两个对象 ...

明天分配名额,差你这几个黑马币呢, 来时有点及时。
作者: 李永昌    时间: 2016-3-18 23:32
Integer a = 1000,b=1000; Integer c = 100,d=100;    public void mRun(final String name){         new Runnable() {                          public void run() {                 System.out.println(name);             }         };     }       System.out.println(a==b);false System.out.println(c==d);false
作者: 李永昌    时间: 2016-3-22 00:29
脑子里记不住东西咋办
作者: 278008379    时间: 2016-3-25 12:36
真的不难
作者: zhudoufu    时间: 2016-4-10 12:13
第一题 false true 吧 Integer是引用类型,他们比较的是地址值,c==d答案我是记住的,原理不懂
作者: zhudoufu    时间: 2016-4-10 12:20
第一题 false true 第二题 true false 第三题 累不累创建的对象在mRun()方法弹栈后依然存在,可能需要访问局部变量,因此用final修饰提高它的生命周期 第四题 true false
作者: linguoqun    时间: 2016-8-2 06:47
==是判断符号左右两边相不相等,=号是赋值符号,将右边的值赋给左边。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2