Java中String、StringBuffer和StringBuilder
来源:互联网 发布:淘宝炉石金币号怎么买 编辑:程序博客网 时间:2024/05/29 16:25
浅析Java中的String、StringBuffer和StringBuilder
一、String
String类是final类,即不能被继承,且其成员方法默认为final方法;
String类的方法都不是在原有的字符串上进行操作,而是重新生成一个新的字符串对象,即进行这些操作后原始的字符串没有改变;
二、String、StringBuffer、StringBuilder
1 String str = "hello"; 和 String str = new String("hello"); 的区别
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); // false System.out.println(str1==str3); // true System.out.println(str2==str4); // false }}
在JVM内存机制中的class文件中有一部分存储编译期间生成的字面常量和符号引用,称为class文件常量池;在运行期间对应着方法区的运行时常量池;
上述代码中String str1 = "hello world"; 和 String str3 = "hello world"; 都在编译期间生成字面常量和符号引用,在运行期间字面常量""hello world"被存储在运行时常量池(只保存一份);通过该方式将String对象跟引用绑定,JVM执行引擎先在运行时常量池中查找是否存在相同的字面常量,若存在则直接将引用指向已存在的字面常量;否则在运行时常量池开辟一个空间来存储字面常量,并将引用指向该字面常量;
通过new关键字生成的对象是在堆内存进行的,而在堆内存进行对象生成的过程是不会检测该对象是否已存在,因此通过new创建对象一定是不同的对象,即使字符串的内容是相同的;
2 String、StringBuffer、StringBuilder
2.1 String和StringBuffer
public class Main { public static void main(String[] args) { String string = ""; for(int i=0;i<10000;i++){ string += "hello"; } }}
string += "hello";的过程相当于将原有的string变量指向的对象内容取出与"hello"作字符串相加操作,再存入另一个新的String对象当中,再让string变量指向新生成的对象;
该循环结束后new了10000个对象;
public class Main { public static void main(String[] args) { StringBuilder stringBuilder = new StringBuilder(); for(int i=0;i<10000;i++){ stringBuilder.append("hello"); } }}
该循环结束后只new了1个对象;
2.2 StringBuffer和StringBuilder
StringBuffer和StringBuilder区别在于StringBuffer类的成员方法前有synchronized关键字,在多线程访问时起到安全保护作用,即StringBuffer是线程安全的;
2.3 使用场景
String、StringBuffer和StringBuilder的执行效率是StringBuffer > StringBuilder > String(相对地);
当字符串相加操作或改动较少时,建议使用String;
当字符串相加操作或改动较多时,建议使用StringBuilder;
若采用多线程,建议使用StringBuffer;
三、常见面试题
1 下面这段代码的输出结果?
String a = "hello2"; String b = "hello" + 2; System.out.println((a == b));
输出为true,因为"hello"+2在编译期间优化成"hello2",因此在运行期间变量a和b指向的是同一对象;
2 下面这段代码的输出结果?
String a = "hello2"; String b = "hello"; String c = b + 2; System.out.println((a == c));
输出为false,因为有符号引用存在,String c = b + 2;不会在编译期间优化,即不会将b + 2当作字面常量处理,这种方式生成的的对象保存在堆上,因此a和c指向不同对象;
3 下面这段代码的输出结果?
String a = "hello2"; final String b = "hello"; String c = b + 2; System.out.println((a == c));
输出为true,因为被final修饰的变量在class文件常量池中保存一个副本,对final变量的访问在编译期间直接替换成真实的值,因此String c = b + 2;在编译期间优化成String c = "hello" + 2;;
4 下面这段代码的输出结果?
public class Main { public static void main(String[] args) { String a = "hello2"; final String b = getHello(); String c = b + 2; System.out.println((a == c)); } public static String getHello() { return "hello"; }}
输出为false,因为虽然b用final修饰,但其赋值是通过方法调用返回的,其值只能在运行期间确定,因此a和c指向不是同一个对象;
5 下面这段代码的输出结果?
public class Main { public static void main(String[] args) { String a = "hello"; String b = new String("hello"); String c = new String("hello"); String d = b.intern(); System.out.println(a==b); System.out.println(b==c); System.out.println(b==d); System.out.println(a==d); }}
输出为false false false true,因为String类的intern方法是本地方法,在Java SE6之前,intern方法在运行时常量池中查找是否存在内容相同的字符串,若存在则返回指向该字符串的引用,若不存在则将字符串入池,返回一个指向该字符串的引用;
6 String str = new String("abc");涉及几个String对象?
2个,因为在类加载过程中,在运行时常量池中创建一个"abc"对象;在执行过程中,在堆上创建一个"abc"对象;
7 下面这段代码1>和2>的区别?
public class Main { public static void main(String[] args) { String str1 = "I"; //str1 += "love"+"java"; 1> str1 = str1+"love"+"java"; //2> }}
1>比2>效率高,因为1>中的"love"+"java"在编译器期间优化成"lovejava",而2>中的不会优化;
在命令行窗口键入"javap -c Main",发现1>中只进行1次append操作,2>中进行2次append操作;
注明:此文章是转载海子的博文,详情见:http://www.cnblogs.com/dolphin0520/p/3778589.html
- java中String和StringBuffer和StringBuilder
- java中String和StringBuffer、StringBuilder
- Java中String、StringBuffer和StringBuilder详解
- java中String、StringBuffer和StringBuilder区别
- Java中String和StringBuffer、StringBuilder
- Java中String、StringBuffer和StringBuilder
- java中string stringbuffer和stringBuilder区别
- Java中String、StringBuilder和StringBuffer
- java中String、StringBuilder和StringBuffer初解
- java中关于String、StringBuffer和StringBuilder
- java中String、StringBuffer、StringBuilder
- java中String、StringBuffer、StringBuilder
- java String,StringBuffer和StringBuilder
- java String,StringBuffer和StringBuilder
- Java String、StringBuffer和StringBuilder
- [Java]String、StringBuilder和StringBuffer
- 【Java】Java中,String、StringBuffer和StringBuilder的区别
- Java中String ,StringBuffer和StringBuilder的区别和用法
- [leetcode] 19. Remove Nth Node From End of List
- 泛型接口(C# 编程)
- 就是现在
- HP-UX 使用SAM进行Printer设定
- 2016MUTC3-1007 Explorer Bo
- Java中String、StringBuffer和StringBuilder
- 泛型方法(C# 编程)
- 21编码问题
- 22编码问题
- Android中大图片加载及快速浏览处理
- flow.js 一个多线程的、稳定、可恢复的上传文件JS类库
- 泛型和数组(C# 编程)
- 泛型委托(C# 编程)
- Web 前端 UI 框架 Bootstrap