一、三者的区别概述

  1.可变与不可变:String底层使用final修饰的字符数组来存储字符串,它属于不可变类,对String对象的任何改变操作都不会改变原对象,而是生成一个新对象。StringBuilder和StringBuffer有一个共同的抽象父类AbstractStringBuiler,它们底层是一个不用final修饰的字符数组,因此它们是可变的。

   2.是否线程安全:String由final修饰,因此必然是线程安全的。StringBuilder与StringBuffer的唯一区别就是StringBuffer的方法都加上了syncharnized,因此StringBuffer是线程安全的。

      3.执行效率:StringBuilder > StringBuffer > String

二、对String的深入剖析

1.String str="hello world"和String str=new String("hello world")的区别

private static void test1() {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);}

运行结果:

false
true
false

在class文件中有一部分用来存储编译期生成的字面常量以及符号引用,这部分叫做class文件的常量池,在运行期间对应着方法区的运行时常量池。上面代码中str1,str2在编译期间都会生成字面常量和符号引用,运行时会将字面常量保存在方法区的运行时常量池,只保存一份,将引用和对象进行绑定时会检查常量池中是否存在相同的字面常量,有则直接绑定,没有则新建,因此可知str1,str2指向的是同一个字面常量,而new操作是在堆区新建对象,肯定是产生了新的对象。

2.

private static void test2() {String a = "hello2";String b = "hello" + 2;System.out.println((a == b));}

运行结果:true

在编译期"hello" + 2被优化为hello2,因此a,b指向的是同一个对象。

3.

private static void test3() {String a = "hello2";String b = "hello";String c = b + 2;System.out.println((a == c));}

运行结果:false

由于存在符号引用,b+2并不会被编译器优化,只有处理字面常量时才会有优化。因此c,a是两个不同的对象。

4.

private static void test4() {String a = "hello2";final String b = "hello";String c = b + 2;System.out.println((a == c));}

运行结果:true

由于b被final修饰,属于一个常量,编译器会进行优化,对final变量的访问在编译期间都会直接被替代为真实的值,因此c = "hello" + 2。

5.

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指向不同的对象。

6.

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方法会在运行时常量池中查找是否存在内容相同的字符串,如果存在则返回指向该字符串的引用,如果不存在,则会将该字符串入池,并返回一个指向该字符串的引用。因此,a和d指向的是同一个对象。

7.String str = new String("abc")创建了多少个对象?

创建了一个对象,涉及到两个对象。在类加载的过程中,在运行时常量池中创建了一个"abc"对象,而在代码执行过程中只创建了一个String对象。

8.

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)中的不会被优化。

个人总结:编译器是否会在编译期优化取决于取决于这个"常量"在编译期是否是一个确定的值,以及它是否是一个字面常量,如果存在引用符号则不会优化。

参考链接:https://www.cnblogs.com/dolphin0520/p/3778589.html

     https://www.cnblogs.com/xudong-bupt/p/3961159.html

转载于:https://www.cnblogs.com/jxxblogs/p/11027901.html

String、StringBuiler、StringBuffer的区别相关推荐

  1. String与StringBuffer的区别

    String与StringBuffer的区别 简单地说,就是一个变量和常量的关系.StringBuffer对象的内容可以修改:而String对象一旦产生后就不可以被修改,重新赋值其实是两个对象. St ...

  2. JAVA中String与StringBuffer的区别

    String和StringBuffer的区别,网上资料可以说是数不胜数,但是看到这篇文章,感觉里面做的小例子很有代表性,所以转一下,并自己做了一点总结. 在java中有3个类来负责字符的操作. 1.C ...

  3. String和StringBuffer的区别,String长度是固定的?

    String和StringBuffer的区别,String长度是固定的? 区别: 1. String类字符串的长度是固定的,StringBuffer类字符串的长度是可变的.因为String改变的是地址 ...

  4. Java中string与String区别_JAVA中String与StringBuffer的区别

    JAVA中String与StringBuffer的区别 2009-12-3文字大小:大中小 在java中有3个类来负责字符的操作. 1.Character 是执行 单个字符操作的, 2.String ...

  5. Java中String 和StringBuffer的区别

    先看下面的这个例子,读懂这个例子,你就理解了. publicclass Test { publicstaticvoid stringReplace (String text) { text = tex ...

  6. java中string 和stringbuffer的区别_Java中的String,StringBuilder,StringBuffer三者的区别...

    最近在学习Java的时候,遇到了这样一个问题,就是String,StringBuilder以及StringBuffer这三个类之间有什么区别呢,自己从网上搜索了一些资料,有所了解了之后在这里整理一下, ...

  7. String Stringbuilder StringBuffer的区别和应用

    1.可变与不可变 1) String类中使用字符串数组来保存字符串.因为有final修饰,所以,String对象是不可变的 private final char vakue[]; 2) StringB ...

  8. String和StringBuffer的区别

    参考资料:http://blog.csdn.net/lclai/article/details/6141548 其实就是把别人的博文扒了下来,加深一下印象. 首先,StringBuffer对象的内容可 ...

  9. String 和 StringBuffer 的区别

    为什么80%的码农都做不了架构师?>>>    String: 是对象不是原始类型. 为不可变对象,一旦被创建,就不能修改它的值. 对于已经存在的String对象的修改都是重新创建一 ...

  10. String , StringBuffer 和 StringBuilder 区别

    转载:http://www.blogjava.net/chenpengyi/archive/2006/05/04/44492.html 相信大家对 String 和 StringBuffer 的区别也 ...

最新文章

  1. 算法设计思想(2)— 贪婪法
  2. 在部署 C#项目时转换 App.config 配置文件
  3. FFmpeg的C++封装:FFmpegWrapper
  4. 文本识别新王者CharNet:卷积字符网络
  5. 最详细,快速入门Web前端开发的正确姿势
  6. Windows Server 2008 R2 成功安装 Serv-U
  7. ftp协议是一种用于什么的协议_购房协议怎么写?签购房协议要注意什么
  8. 火狐浏览器书签不同步问题
  9. 摩尔庄园服务器维护,《摩尔庄园》6月11日维护公告
  10. 凯恩帝数控系统面板介绍_KND凯恩帝数控系统说明书
  11. 手机定向root,指定APP获取root权限
  12. 伊利诺伊香槟分校计算机科学,UIUC的CS「伊利诺伊大学香槟分校计算机科学系」...
  13. 图像分割之分水岭算法
  14. 图文并茂详细教程之-- 用pixhawk飞控组装一台F450四轴无人机(下)
  15. [Luogu P2713] 罗马游戏
  16. TextView文本尾部添加标签,支持自动换行
  17. 新华三发布《中国城市数字经济指数白皮书(2019)》,融绘数字中国蓝图用数据记录城市数字化转型进程!
  18. 数字化转型大咖群研讨实录20210506
  19. php酷狗音乐json,酷狗音乐API接口
  20. Zero-sho原先的升级版:hourglass网络:U-Net

热门文章

  1. 系统学习NLP(十二)--文本表示综述
  2. microbit与python编程_简单5步开始学习microbit编程-windows篇
  3. r语言把多个图合并在一张图_R语言绘图 | 折线图画法,如何画出你满意的图?
  4. Windows10下VB6.0开发——ini文件存储参数信息
  5. 指针变量的所占字节数大小确定
  6. clickhouse条件函数
  7. bzoj4987: Tree(树形dp)
  8. 使用p4c将P4 14代码转换为16代码
  9. IOS-UIButton的文本与图片的布局
  10. Python 2.5.1 切片