String用new与不new的区别
String str1=“ABC”:可能会创建一个或不创建对象:如果常量池中有“ABC”,则不创建对象,直接指向那个地址,如果没有,则在常量池中创建一个新的值为“ABC”的对象。
String str2 = new String(“ABC”):一定会创建一个对象,可能创建两个对象:先在堆中开辟一个空间,将那个空间的地址给str2(创建了第一个对象),然后取常量池中,看有无“ABC”,如果有,则将这个地址给堆中开辟的空间,如果没有,则新建一个值为“ABC”的对象(创建了第二个对象),将这个新创建的对象给堆中开辟的那个空间。

即str1中存的是堆中分配的空间,堆中分配的空间中存的是字符串常量池中分配空间存放”ABC”的空间的地址值。而str2中之间存的是字符串常量池中分配空间存放”ABC”的空间的地址值。
https://blog.youkuaiyun.com/zhouhuocleverset/article/details/61935578
public static void main(String[] args) {
String str1=new String("ABC");
String str2=new String("ABC");
System.out.println(str1==str2);//false
String str3 = "ABC";
String str4 = "ABC";
String str5 = "AB" + "C";
System.out.println(str3 == str4); //true
System.out.println(str3 == str5); // true
//对于字符串常量的+号连接,在程序编译期,JVM就会将其优化为+号连接后的值。
String a = "ABC";
String b = "AB";
String c = b + "C";
//对于字符串引用的+号连接问题,字符串引用在编译期无法确定下来
//所以只能在程序的运行期动态分配并创建新的地址存储对象。
/*此时创建了一个StringBuffer对象,调用append来拼接b和"C",
然后调用toString方法,生成一个新的String对象*/
System.out.println(a==c);//false 此时c是引用变量
c = c.intern();//如果c在常量池中,直接返回,如果不在,返回常量池中该对象的值
System.out.println( a == c );//true 所以此时a和c都是指向常量池中的值
String d="abc2";
String e="abc";
String f=e+2;
String g=e+2;
System.out.println(f==g);//false
System.out.println(d==f);//false
/*f,g都是引用变量,而d,e都是常量池中的变量*/
final String i="abc";
String j="abc2";
String k=i+2;
System.out.println(k==j);//true final修饰的变量是一个常量,编译期就能确定其值
}
- 所以在平时用String s1=“abcd”这种方式更好,因为new一定会创建一个新的对象,一定会占用新的空间。
- 如果在循环里面要拼接字符串的话,不适合用+拼接,因为每用一次+号就会新生成一个StringBuilder对象,就很浪费。可以在循环外生成一个StringBuilder对象(或StringBuffer),然后在循环里直接调用append方法来拼接。
public static void main(String[] args){
StringBuilder s = new StringBuilder();
for(int i = 0; i < 100; i++){
s.append("a");
}
}
参考 https://blog.youkuaiyun.com/u013759354/article/details/88849815
本文详细探讨了Java中String对象通过`new`关键字与直接赋值创建的区别。使用`new`始终会创建新对象,而直接赋值可能复用常量池中的对象。在循环拼接字符串时,使用StringBuilder更有效率。文章还介绍了字符串常量池、intern()方法以及编译期优化。最后,提供了优化字符串操作的实践建议。

被折叠的 条评论
为什么被折叠?



