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??
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??
hello在编译期不能被确定
lo也在编译期不能被确定
所以上面的代码不能在编译期被优化和内联,"Hel" + lo返回为一个String对象,但此对象并没有被intern化,因为没有intern化的必要,除非显式调用intern方法
"Hel"+"lo"编译器优化为"Hello",因常量池已存在,所以直接引用该对象
"Hel"+lo会在堆中生成一个新的对象,和常量池不是同一个对象
("Hel"+lo).intern 如果常量池中不存在"Hello",inern方法会把堆中的"Hello"对象保存到常量池,否则什么也做,同时返回常量池中的引用
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.
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());
}
}
你再看一下结果哦
System.out.println("ab" == "a" + b);//与对象相加相当于new出一个对象。
System.out.println("ab" == "a" + "b");//都在String pool中
比较这两种情况。看着就知道了:
http://blog.csdn.net/daijope/article/details/6559531
前提: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。
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());
}
}这个没有任何区别
那么意思就是说:用intern()方法的话“开辟字符串新地址”是与常量池中的字符串地址一样吧?!而在"Hello"+lo中创建的地址是不同常量池的吧?!是这样理解吗
你的理解大体是对的