String a = "hello";
String b = new String("hello");
final String c = "hello";
一、直接定义和new String的区别(即a和b的区别)
a指向常量池,而b指向堆。在java中,遇到new关键字,即会在堆中创建对象。String b = new String("hello")时会先去常量池中找是否有"hello",如果常量池中没有,则先在常量池中新建"hello",然后在堆中创建一份拷贝对象,然后把堆内存中对象的地址赋给b。所以,String b = new String("hello");有可能创建了两个对象。
所以 a == b 是false(==是直接比较地址值,而String的equals是先比较地址值,不相等再逐个比较字符,所以a.equals(b)是true)
二、final修饰String
final修饰类的时候表示类不可被继承
final修饰方法的时候表示方法不能被重写
final修饰变量的时候,表示变量不可变
所以,final String c = "hello";仅仅表示c不可变,不可再被重新赋值。(注意:这个String类是final的无关,那个是修饰String类的)
final修饰的String在相加的时候等同于字符串直接相加:
final a = "a",
final b = "b";
a+b == "a"+"b" == "ab"
因为+号两边都是常量,其值在编译期就可以确定,由于编译器优化,在编译期就将+两边拼接合并了,直接合并成是一个常量"ab"。
但是如果把final去掉,a+b == "a" + "b" 就是false了,因为不用final修饰,a和b都是对象,在编译期无法确定其值,所以要等到运行期再进行处理,处理方法:先new一个StringBuilder,然后append a和 b,最后相加的结果是一个堆中new出来的一个对象
可参考http://www.mamicode.com/info-detail-2370655.html
