一、三者的区别概述

  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://blog.csdn.net/weixin_35235724/article/details/112080445

String、StringBuiler、StringBuffer的区别的更多相关文章

  1. JAVA中String与StringBuffer的区别

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

  2. String 和 StringBuffer的区别

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

  3. boolean和Boolean, char和Character , byte和Byte, short和Short, int和Integer , long和Long , float和Float, double和Double的区别 , String和StringBuffer的区别

    Java提供两种不同的类型:引用类型和原始类型(内置类型).Int是java的原始数据类型,Integer是java为int提供的封装类. Java为每个原始数据类型提供了封装类. 其中原始数据类型封 ...

  4. string 和 stringbuffer的区别?

    string和stringbuffer的区别其实是变量和常亮的关系,string和stringbuffer内部实现的原理不同,在修改string对象时会产生另外的对象,也就是说在内存中会有两个存储区域 ...

  5. 【转载】String和StringBuffer的区别,以及StringBuffer的常用方法介绍

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

  6. String和StringBuffer的区别

    1.选自http://szh-java.iteye.com/blog/1666630 String 1,Stirng是对象不是基本数据类型 2,String是final类,不能被继承.是不可变对象,一 ...

  7. String与StringBuffer的区别

    首先,String和StringBuffer主要有2个区别: (1)String类对象为不可变对象,一旦你修改了String对象的值,隐性重新创建了一个新的对象,释放原String对象,StringB ...

  8. String和StringBuffer的区别;字符串的一些基本方法

    String 和 StringBuffer区别 字符串广泛应用 在Java 编程中,在 Java 中字符串属于对象,Java 提供了 String 类来创建和操作字符串. 需要注意的是,String的 ...

  9. Java语言基础(四) String和StringBuffer的区别

    Java提供了两个字符串类:String和StringBuffer. String提供了数值不可变的字符串,而StringBuffer提供的字符串对象可以进行修改. 当知道字符数据要改变的时候就可以使 ...

  10. java中String和StringBuffer的区别

    前言 String和StringBuffer本质上都是修饰字符串的只是含义不同 StringBuffer叫做字符串缓冲区 首先看下string类的例子 public class Work1 { pub ...

随机推荐

  1. 数据透视:Excel数据透视和Python数据透视

    作者 | leo 早于90年代初,数据透视的概念就被提出,主要的应用场景是处理大量数据的交互式汇总查询,它实现了行或列的移动,使得行可以移到列上,列移到行上,从而根据使用者的诉求取对关注的数据子集进行 ...

  2. [GAMEDEV] 个人开发如何找到合适的图片素材?

    1. 起因 起因是想找一些UI设计方面的素材(具体地说,类似于Web或者App上一些按钮/页签/进度条等元素),用到游戏GUI中来,毕竟扁平化的网页设计还是很清爽的. 本以为这方面的素材会比游戏中的图 ...

  3. 挖到一款免费好用的web报表插件

    最近公司项目需要用到报表,公司领导要求我来调研下报表工具.开始的时候了解了目前市场上功能强大,占有率高的两款报表工具,帆软报表和润乾报表,这两款报表工具功能比较强大,覆盖的行业较广,基本能满足所有的报 ...

  4. Smartbi报表工具的学习笔记,如何学好报表分析?

    近期,因为工作需要,学习了一个报表工具Smartbi,这是国产BI软件,其功能还是挺强大的,并且学习成本很低,容易上手. 其实在学习Smartbi之前,我还学习了一段时间的微软BI工具sqlserve ...

  5. Ecma335、CLR、CLI、CTS、 IL、.net 以及他们之间的关系

    以上是个人对他们直接关系的理解:图片是原创 CLI 通用语言基础架构(Common Language Infrastructure), CLI是一个开放型的技术规范,它定义了一个语言无关的跨体系结构的 ...

  6. C#(1):XML DOM、System.Xml.XmlDocument

     一.XML DOM概述 XML 文档大小写敏感.属性用引号括起来,每一个标记都要闭合. DOM是XML文档的内存中树状的表示形式. 继承关系图: XmlNode;//XML节点 ......Xml ...

  7. 正则表达式(三)——Java中的相关函数

    1.前言 之前在学习Python时,我已经说过正则表达式的相关语法,这里不再赘述了,有需要可以参考: 2020.10.7 正则表达式(一) - ShineLe - 博客园 现在开始学习Java中的正则 ...

  8. think php 上下架修改+jq静态批量删除+ajax删除+全选

    视图代码: <!doctype html> <html lang="en"> <head> <meta charset="UTF ...

  9. 被广泛使用的OAuth2.0的密码模式已经废了,放弃吧

    最近一直有同学在问,OAuth2密码模式为啥Spring Security还没有实现,就连新的Spring Authorization Server也没有这个玩意儿. 其实这里可以告诉大家,OAuth ...

  10. Ubuntu 16.04 更改系统语言为简体中文

    镜像下载.域名解析.时间同步请点击阿里巴巴开源镜像站 一.安装时报错 原因:以访客的身份进入的会报错,改为管理员进入即可. ps:有时候往往一点小细节也会造成大问题,但是我们要善于排错. 注:可以看到 ...