class Other {
static String hello = "Hello";
}public class newTest {
public static void main(String[] args) {
String hello = "Hello", lo = "lo";

System.out.print((hello == "Hello") + " ");
System.out.print((Other.hello == hello) + " ");
System.out.print((Other.hello == hello) + " ");
System.out.print((hello == ("Hel"+"lo")) + " ");
System.out.print((hello == ("Hel"+lo)) + " ");
System.out.print(hello == ("Hel"+lo).intern());
}
}特别是:System.out.print((hello == ("Hel"+lo)) + " ");  这一行的结果为什么是false??

解决方案 »

  1.   

    还是不明白,为什么要用equals才行呢?到底("Hel"+lo)这里出了什么问题呢?
      

  2.   

    特别是:System.out.print((hello == ("Hel"+lo)) + " "); 这一行的结果为什么是false??
    hello在编译期不能被确定
    lo也在编译期不能被确定
    所以上面的代码不能在编译期被优化和内联,"Hel" + lo返回为一个String对象,但此对象并没有被intern化,因为没有intern化的必要,除非显式调用intern方法
      

  3.   

    呃小弟还是不明白,,,什么是intern化;还有,优化和内联是怎么回事啊“编译期不能被确定”是指编译器运行时赋值的意思吗??
      

  4.   

    呃小弟还是不明白,,,什么是intern化;还有,优化和内联是怎么回事啊“编译期不能被确定”是指编译器运行时赋值的意思吗??
      

  5.   

    "Hello"是常量池的一个对象
    "Hel"+"lo"编译器优化为"Hello",因常量池已存在,所以直接引用该对象
    "Hel"+lo会在堆中生成一个新的对象,和常量池不是同一个对象
    ("Hel"+lo).intern 如果常量池中不存在"Hello",inern方法会把堆中的"Hello"对象保存到常量池,否则什么也做,同时返回常量池中的引用
      

  6.   

    java中比较字符串的值只能用equals,在字符串中==是用来比较地址的。
      

  7.   

    楼主要想理解这个问题,就必须要有这样两个基础
    1. JVM里面的“常量池”的概念
    2. ==比较的是内存地址,而不一定是内容。所有字符串直接数 类似String hello = "Hello";这样的常量“Hello”都会在编译的时候放到常量池当中,后面JVM再次使用常量“Hello”实际上是从常量池当中直接取,因此内存地址一样,==比较的前三个肯定true没问题。
       同时,JVM类似String a=“Hel”+“lo”;这样的语法(简单的由字符串直接数拼接),在编译的时候会根据拼接的结果,如果拼接结果在常量池有,则直接使用,没有则创建放到常量池。因此第四个也是true没问题
       对于最疑惑的这个,是因为(hello == ("Hel" + lo))进行比较的时候,lo无法在编译期确定也没有强制内联化(也就是执行String.intern()),在运行的时候会不管常量池是否有对应量,而径直直接新建一个字符串内存,与之前的常量池内存不同,所以被比较为false
       最后这个的解释,就是在JVM运行的时候,利用String.intern进行了内联优化,也就是运行分配变量内存首先进行一步比较,首先看看常量池有没有“Hello”,如果有则使用,如果没有则开辟字符串新地址,本例里面有这个“Hello”,所以执行结果为true.
      

  8.   

    楼主可以参考 http://tech.163.com/06/0220/23/2AEKS6HJ0009159T.html 学习下
      

  9.   

    class Other {
     static final String hello = "Hello";
    }public class newTest {
     public static void main(String[] args) {
     String hello = "Hello", lo = "lo"; System.out.print((hello == "Hello") + " ");
     System.out.print((Other.hello == hello) + " ");
     System.out.print((Other.hello == hello) + " ");
     System.out.print((hello == ("Hel"+"lo")) + " ");
     System.out.print((hello == ("Hel"+lo)) + " ");
     System.out.print(hello == ("Hel"+lo).intern());
     }
    }
    你再看一下结果哦
      

  10.   

    不去学深入虚拟机,就不要想这么多,只要知道除了基础类型外,除非要判断是否同个对象,否则都用 equals
      

  11.   

    如果==的话是判断是不是指向同一个对象,这人明显是两个对象,所以是true,equals是比较值相等
      

  12.   

    String b = "b";
    System.out.println("ab" == "a" + b);//与对象相加相当于new出一个对象。
    System.out.println("ab" == "a" + "b");//都在String pool中
    比较这两种情况。看着就知道了:
    http://blog.csdn.net/daijope/article/details/6559531
      

  13.   

    字符串比较时, ==是比较是否指向内存中同一个对象,equals()才是判断两个字符串是否包含同样的字符序列
      

  14.   

    正解,我来解释一下。
    前提:String hello = "Hello", lo = "lo";
    解答:
    1.先看这中情况:hello == "Hel"+"lo";//true,因为"Hel"+"lo"会被编译器优化,直接放入字符串池中。而String hello="Hello",也是在字符串池中,所以为true.2.对于它"Hel"+lo,编译器读到这句的时候,由于lo是变量,所以不确定"Hel"+lo之后的值会不会在字符串池中,所以这种情形编译器会把这个结果用另外一个变量存储,并且是存储在堆栈中,而String hello = "Hello"是存储在字符串池中,所以"Hel"+lo值是false。
      

  15.   

    java里面要判断字符串相等时通过equals来判断的,而==只有对象相同时才有效,自己体会一下
      

  16.   

    class Other {
     static final String hello = "Hello";
    }public class newTest {
     public static void main(String[] args) {
     String hello = "Hello", lo = "lo"; System.out.print((hello == "Hello") + " ");
     System.out.print((Other.hello == hello) + " ");
     System.out.print((Other.hello == hello) + " ");
     System.out.print((hello == ("Hel"+"lo")) + " ");
     System.out.print((hello == ("Hel"+lo)) + " ");
     System.out.print(hello == ("Hel"+lo).intern());
     }
    }这个没有任何区别
      

  17.   


    那么意思就是说:用intern()方法的话“开辟字符串新地址”是与常量池中的字符串地址一样吧?!而在"Hello"+lo中创建的地址是不同常量池的吧?!是这样理解吗
      

  18.   

    我理解的intern()方法所谓的“内联优化”就是多了一步比照,如果想要创建的字符串已经在常量池里面,那么就直接用常量池的,而不会创建。而不执行“内联优化”就是完全不做这一步,直接调用新的内存。
    你的理解大体是对的