Java300集零基础适合初学者视频教程←点击
String、StringBuffer、StringBuilder
1.String STR ="hello world" and String STR =new String("hello world")
想必您熟悉上面的两条语句,在通常的代码编写过程中经常会遇到,那么它们之间有什么区别和联系呢?以下是一些例子:
public class Main {
public static void main(String[] args) {
String str1 = "hello world";
String str2 = new String("hello world");
String str3 = "hello world";
String str4 = new String("hello world");
System.out.println(str1==str2);
System.out.println(str1==str3);
System.out.println(str2==str4);
}
}
这段代码的输出结果为
为什么会发生这种情况?原因如下:
正如在之前关于JVM内存机制的文章中提到的,类文件中有一节存储在编译期间生成的文字常量和符号引用。这部分称为类文件常量池,它对应于方法区域的运行时常量池。
所以在上面的代码中,String str1 = "Hello world";str3 = "Hello world";文字常量和符号引用都是在编译时生成的,运行时文字常量“Hello World”存储在运行时常量池中(当然,只有一个副本)。要以这种方式将String绑定到引用,JVM执行引擎首先在运行时常量池中寻找相同的文字常量,如果是,则直接将引用指向已经存在的文字常量。否则,在运行时常量池中创建一个空间来存储文字常量并引用它。
如您所知,通过new关键字生成的对象是在堆中完成的,而堆中的对象生成并不检测对象是否已经存在。如果你用new创建一个对象,你会创建一个不同的对象,即使字符串的内容是相同的。
2. StringBuffer和StringBuilder之间的区别
为什么我们需要StringBuilder和StringBuffer类,当我们在Java中已经有了String类?
看看这段代码:
public class Main {
public static void main(String[] args) {
String string = "";
for(int i=0;i<10000;i++){
string += "hello";
}
}
}
这个字符串+= "hello";等价于在字符串中添加“Hello”并将其存储在一个新的字符串中,并使该字符串指向新生成的对象。如果你有任何问题,反编译它的字节码文件:
从这个反编译的字节码文件中可以清楚地看到,整个循环从第8行执行到第35行,每个循环创建一个New StringBuilder对象,添加它,并通过toString方法返回一个String。也就是说,在执行循环之后,已经创建了10,000个新对象。想象一下,如果没有收集这些对象,会浪费多少内存。string+="hello"操作实际上是由JVM自动优化的:
StringBuilder = new StringBuilder(string);
str.append(“hello”);
str.toString ();
看看下面的代码:
public class Main {
public static void main(String[] args) {
StringBuilder stringBuilder = new StringBuilder();
for(int i=0;i<10000;i++){
stringBuilder.append("hello");
}
}
}
反编译字节码文件得到:
从这里可以清楚地看到,代码的for循环从第13行开始,到第27行结束,而且新操作只完成一次,也就是说,只生成一个对象,而追加操作是在原始对象上完成的。因此,在10,000次循环之后,这段代码占用的资源要少得多。
有人可能会问为什么我们有一个StringBuilder类还需要一个StringBuffer类呢?如果查看源代码,可以看到StringBuilder和StringBuffer具有本质上相同的成员属性和方法。区别在于StringBuffer类的成员方法前面有一个关键字:Synchronized,不用说,是一个受多线程访问保护的关键字,这意味着StringBuffer是线程安全的。
下面的代码片段来自StringBuffer和StringBuilder。
StringBuilder的插入方法
public StringBuilder insert(int index, char str[], int offset,
int len)
{
super.insert(index, str, offset, len);
return this;
}
StringBuffer的insert方法:
public synchronized StringBuffer insert(int index, char str[], int offset,
int len)
{
super.insert(index, str, offset, len);
return this;
}
想要系统学习JAVA推荐JAVA300集
Java300集零基础适合初学者视频教程←点击



