一、创建String对象的两种方式
String pool is a reserved memory area in heap memory which Java uses for storing string constants.
String常量池是堆中一块内存,它用来存储String常量。
(在JDK1.8之前,常量池放在堆外,在JDK1.8之后,类的元信息放在堆内)
Two ways to create string
String s1 = new String("hello");
String s2 = new String("hello");
String s3="hello";
String s4=s1.intern();
String s5=s3.intern();
①String s1 = new String(“hello”);
Object created in both Heap and SCP(String constans pool).reference to object in Heap(Add1) has been assigned to s1.
分别在Heap和SCP中创建了对象,S1指向Addr1
②String s2 = new String(“hello”);
Objects has to be created in both Heap and SCP.But since SCP already has an object with same content so object has not been created in SCP.reference to object in heap (Add3)has been assigned to s2.
分别在Heap和SCP中创建了对象。但因为SCP中已经有相同对象,所以SCP中不创建。S2指向Addr3.
③String s3=“hello”;
"Hello"是string字面量。所以JVM会在SCP中找"Hello"对象。找到,则S3指向Add2。
④String s4=s1.intern();
Since intern() method returns String object in SCP,we can directly print it.
intern()能返回new 出来对象在SCP中的对象。
⑤String s5=s3.intern();
Using intern() method on a literal also return the reference of SCP object.
从字节码文件中,也可以看出,S1、S2、S3、S4、S5均用的常量池相同的“Hello”对象。
总结这两种创建String对象的方式:
-
In above example, both ways are used to create strings, but later is recommended which uses string literals. String literals always go to string pool.
有两种创建方式,但是用string字面量是被推荐的,因为string字面量总会存入SCP中。 -
When we create string with new keyword, two objects will be created i.e. one in the Heap Area and another in the String constant pool. The created string object reference always points to heap area object.when you create string objects using new keyword, a new object is created whether the content is same or not.
new 创建对象时,会在heap和SCP中创建对象。引用指向heap中的对象。若SCP中已创建,则只创建heap中对象。 -
“When you create a string object using string literal, JVM first checks the content of to be created object. If there exist an object in the pool with the same content, then it returns the reference of that object. It doesn’t create new object. If the content is different from the existing objects then only it creates new object.”
In simple words, there can not be two string objects with same content in the string constant pool. But, there can be two string objects with the same content in the heap memory.
- The Java String intern() return the reference of a equal string literal present in string pool.
String equality is checked with String.equals() method.
二、String Immutable
One more interesting thing about String objects in java is that they are immutable. That means once you create a string object, you can’t modify the contents of that object. If you try to modify the contents of string object, a new string object is created with modified content.
String对象是不可更改的。一旦创建了一个string对象,你不能更改对象。若要更改,则会创建一个新的对象。
①字面量
String s1="hello";
String s2 = "hello";
s1="everybd";
String s3=new String("hello");
如下图,s1更改时,并没有将Addr1中的“hello”改为“everybd”,而是新创建了一个“everybd”,让s1指向它。
②new 出对象
String objects created using new operator are also immutable although they are stored in the heap memory.
String s1=new String("hello");
s1.concat("everybd");
System.out.println(s1); //hello
public String concat(String str)
{
int otherLen = str.length();
if (otherLen == 0) {
return this;
}
int len = value.length;
char buf[] = Arrays.copyOf(value, len + otherLen);
str.getChars(buf, len);
//从返回值可以看出,是new了一个对象,而不是在原对象上改
return new String(buf, true);
}
总结:
Immutability is the fundamental property of string objects. In whatever way you create the string objects, either using string literals or using new operator, they are immutable.
string对象是不可变的。无论是字面量还是new 出来的。
三、字符串拼接执行优化
String s="Hello";
s+="World";
//反编译代码:
(new StringBuilder()).append(s).append(World).toString()
四、 StringBuffer And StringBuilder
This property of String class may cause some memory issues for applications which need frequent modification of string objects. To overcome this behavior of String class, two more classes are introduced in Java to represent the strings. They are StringBuffer and StringBuilder. Both these classes are also members of java.lang package same as String class.
对于频繁对string进行更改的string对象,按照string方式,会造成内存问题。为了解决这个问题,使用StringBuffer和StringBuilder。
create:只能用new ,不存在字面量 |string可以用new或字面量
Storage Area: 在heap | string在string constant pool 和heap
Thread Safety:任何immutable对象都是线程安全的;StringBuffer线程安全(它的大部分方法是synchronized的),StringBuilder并不是线程安全的。
Performance:StringBuffer为保证线程安全有开销
参考:https://howtodoinjava.com/java/string/java-string-intern-method-example/
https://www.youtube.com/watch?v=vgN9Zab-1RE
https://javaconceptoftheday.com/how-the-strings-are-stored-in-the-memory/
https://javaconceptoftheday.com/example-to-prove-strings-are-immutable/