创建过程
在java 中 我们通过String 直接赋值创建对象 和new String 创建 有着很大区别
下面是创建 s1,s2,s3,s4的过程
String s1 = "str1";
String s2 = "str1";
String s3 =new String("str1");
String s4 =new String("str1");
在图中我们可以看到通过直接赋值的s1和s2指向的是常量池中的同一对象。而s3与s4是在堆中创建了2个不同的对象,内容是一样的,但是地址不同。
String s1 = "str1";
String s2 = "str1";
String s3 =new String("str1");
String s4 =new String("str1");
System.out.println(s1==s2);
System.out.println(s1==s3);
System.out.println(s3==s4);
System.out.println(s1.equals(s3));
System.out.println(s3.equals(s4));
运行这段代码,相信结果对于大家也是显而易见。
其中 == 运算符比较的是地址,而equals比较的他们的值。
通过 直接赋值创建对象 例如 s1="str1",在编译期会去常量池中寻找是否有"str1"这个值,如果没有,则在常量池中创建"str1",如果有,则直接引用。
通过 new String 创建对象 s3=new String("str1"),也会在编译器去常量池中寻找是否有"str1"这个值,如果没有,则在常量池中创建"str1",然后在运行期在堆中创建一个新的"str1"的对象,不管堆中是否已存在值为"str1"的对象。
总结
内存分配:
字符串常量值中没有该值,则创建常量对象,后续直接赋值不会创建且内存地址相同,而new还会在堆中新建一个对象,内存地址不同。
内存效率:
使用直接赋值通常更加高效,因为它可以避免创建不必要的 String 对象,节省内存空间。
使用 new String() 会创建一个新的对象,即使字符串内容相同,也会占用额外的内存空间。
比较操作:
使用 == 比较直接赋值的字符串,比较的是字符串的地址是否相同。
使用 == 比较使用 new String() 创建的字符串,比较的是两个对象的引用是否相同。
在大多数情况下,应该使用 equals() 方法比较字符串的内容是否相同。