String s = new String (“hello”); 与String s2 = “hello”; 创建的区别
对于String s2 = “hello”; 现在栈中创建一个String对象引用的变量s,然后查找hello字符串是否被保存在常量池中,如果没有则会将”hello”放入常量池,最后s将指向这个对象地址,如果已经存在于常量池,则在字符串常量中找到该对象然后s指向该对象 第一种特点是:JVM会自动根据栈中数据的的实际情况来决定是否有必要创建新对象。
对于String s = new String (“hello”); 而言可以分为两步 String object= “hello”; 与 String s = new (object); 第一步参考上面的创建方式, 第二步由于hello 已经创建并保存到常量池,因此JVM只会在堆中创建一个String对象,其值共享栈中已有的值。
String类是不可改变的。
关于字符串的拼接有如下几种情况:
一:
String a = "a1"; //编译期已经确定的值
String a1 = "a"+1;//a1 不会创建新对象直接指向a所指的a1对象
System.out.println(a1);
System.out.println(a==a1);
分析:结果为true,由于a1的值在编译期就确定,其会直接指向对象”a1”。
二:
String b = "b1";
int bb = 1 ;
String b1 = "b"+bb;// 在编译期无法确定值因为bb是变量,只有到运行期才会确定值
System.out.println(b==b1);
分析:结果为false,因为编译其无法确定b1的值,因为bb是变量
三:
String c = "c1";
final int cc =1 ;
String c1 = "c"+cc; // 在编译期是确定的因为cc用final修饰说明其是常量,因此cc实质上已经用1代替
System.out.println(c==c1);
分析:结果为true cc已经为常量,其值在编译器已经确定。
四:
String d = "d1";
final int dd= getDD();//虽然dd用final修饰,但是由于其值是从方法中获取的只能在运行期确定, 所以在编译期仍然无法确定因此仍视为变量
String d1 = "d1"+dd;// 由于dd的缘故因此d1在编译期仍无法确定
System.out.println(d1==d);
}
public static int getDD() {
return 1 ;
}
分析:结果为false ,由于dd的值是从方法中获取,方法的值只有在运行期才能获得,因此编译期仍然无法确定。