public class fourtest {
public static final String i = "b"; public static void main(String args[]) {
String b = "ab";
String a = "a" + i;
System.out.println(a == b);
System.out.println(a.equals(b));
}
}
输出 true, ture。  这个结果是编译器优化的结果。public class fourtest {
public static final String i = null; public static void main(String args[]) {
String b = "anull";
String a = "a" + i;
System.out.println(a == b);
System.out.println(a.equals(b));
}
}输出 false ,true。 这个时候为啥不是true,true。 

解决方案 »

  1.   

    首先:楼主要搞清楚==和equals的区别
    其他的区别先不说最大的区别在于:= =相对于栈中数据的比较; equals相对于堆中数据的比较; 其次:针对第一个例子
    先在栈中创建一个对 String类的对象引用变量i,然后通过符号引用去字符串常量池 里找有没有"b",如果没有,则将"b"存放进字符串常量池 ,并令i指向”b”,如果已经有”b” 则直接令i指向“b”。
    同样的b最后的结果为"ab",将“ab”存放进字符串常量池,并令b指向“ab”,如果已经有”ab” 则直接令b指向“ab”.
    a的如上,最后结果为“ab”,因为已经存在,所以直接令a指向"ab",最后用==或者equals都是为true再次:针对第二个例子
    null是对象,String i = null 
    对于对象的创建,一概在堆中创建新对象,而不管其字符串值是否相等,是否有必要创建新对象。
    所以即使最后a和b的值一样,用==指向的两个相同值的空间,所以为false,而equals仍然为true。最后:这个就是考虑的Java的内存关系,栈内存定义变量,堆内存开辟空间。这是我的一点小理解,随时探讨,呵呵。
      

  2.   

    http://topic.csdn.net/u/20120607/07/9d3a5948-ca38-4eb9-a4f8-63400b34e13a.html
      

  3.   

    第一个例子中,i是final的。不定义final。 则输出 false, true 。 1楼能解释这个问题么
      

  4.   

    这种问题,你用jd-gui反编译一下生成的class文件就明白了
      

  5.   

    这种问题,你用jd-gui反编译一下生成的class文件就明白了
      

  6.   

    这个对于String简单来说就是比较两字符串的Unicode序列是否相当,如果相等返回true;而==是 比较两字符串的地址是否相同,也就是是否是同一个字符串的引用。
    final只对引用的"值"(即内存地址)有效,它迫使引用只能指向初始指向的那个对象,改变它的指向会导致编译期错误。至于它所指向的对象 的变化,final是不负责的。