String ss1="a"+"bc";
String ss2="abc";
System.out.println(ss1==ss2);//true

ss1=ss1+"def";
ss2="abc"+"def";
System.out.println(ss1==ss2);//false---为什么?

解决方案 »

  1.   

    貌似是ss1=ss1+"def";这行等号右面有变量的缘故
      

  2.   

    确实有点日经。String的享元模式,在编译时能立即确定的常量,才能比较好的发挥效用。而且目前这个效果已经是编译器优化后的了;没记错的话,老早以前的Java,第一条也没法true。ss1=ss1+"def"; 运行时才知道ss1的内容,编译器还没那么聪明可以推断出ss1到这里的时候能是个啥。
      

  3.   

    编译期能确定相同的字符串才会指向常量池中同一个字符串
    什么样的编译期就能确定呢?
    那就是由常量来初始化的字符串ss1=ss1+"def";
    右侧有变量,所以编译期不能确定不过再次强调,不需要研究和专这种问题
    java 对此的实现有过改变,难保以后不改
    搞清楚这个问题没有任何意义
      

  4.   

    关键是要弄懂==的含义。
    ==和equal不要用错了
      

  5.   

    1、字符串是放在静态的代码区域,在类一开始被加载的时候此常量就被初始化放在这个区内,而且被全局所共享,所有的访问直接指向他即可。
    刚开始ss1已经存在abc了
    当你在创建一个引用的时候 首先他回去找在静态代码区域里面有没有此常量。
    如果有,相同的,就指向相同的内存地址。
    2、第二次由于内存地址改变了,所以等于false  
    “==” 是比较栈内存地址是否一样 
      

  6.   

    第一个好解释,都是放在栈里的同一内容!第二个,因为你用到了ss1=ss1+"def",所以这个时候的ss1已经被先转换为对象了,然后虚拟机会新建一个new String("def");然后在和ss1相加,结果也是一个字符串对象,这个时候ss1已经放在堆里面了!而ss2还只是一般的字符串相加自然还是放在栈里面,这个时候放的地方都不一样了,在用等号比较肯定是false了