String, StringBuffer and StringBuilder
一 String
概述:
String 被声明为 final,因此它不可被继承。
在 Java 8 中,String 内部使用 char 数组存储数据。
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[];
}
在 Java 9 之后,String 类的实现改用 byte 数组存储字符串,同时使用 coder 来标识使用了哪种编码。
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final byte[] value;
/** The identifier of the encoding used to encode the bytes in {@code value}. */
private final byte coder;
}
value 数组被声明为 final,这意味着 value 数组初始化之后就不能再引用其它数组。并且 String 内部没有改变 value 数组的方法,因此可以保证 String 不可变。
不可变的好处:
1 可以缓存hash值
因为 String 的 hash 值经常被使用,例如 String 用做 HashMap 的 key。不可变的特性可以使得 hash 值也不可变,因此只需要进行一次计算。
2 String pool的需要
如果一个 String 对象已经被创建过了,那么就会从 String Pool 中取得引用。只有 String 是不可变的,才可能使用 String Pool。
String str1 = "abc"; String str2 = "abc"; System.out.println(str1==str2);//true
3 安全性
String 经常作为参数,String 不可变性可以保证参数不可变。例如在作为网络连接参数的情况下如果 String 是可变的,那么在网络连接过程中,String 被改变,改变 String 对象的那一方以为现在连接的是其它主机,而实际情况却不一定是。
4 线程安全
String 不可变性天生具备线程安全,可以在多个线程中安全地使用。
String, StringBuffer and StringBuilder
1 可变性
- String 不可变
- StringBuffer 和 StringBuilder 可变
2 线程安全
- String 不可变,因此是线程安全的
- StringBuilder 不是线程安全的
- StringBuffer 是线程安全的,内部使用 synchronized 进行同步
String Pool
字符串常量池(String Pool)保存着所有字符串字面量,这些字面量在编译时期就确定。不仅如此,还可以使用 String 的 intern() 方法在运行过程中将字符串添加到 String Pool 中
当一个字符串调用 intern() 方法时,如果 String Pool 中已经存在一个字符串和该字符串值相等(使用 equals() 方法进行确定),那么就会返回 String Pool 中字符串的引用;否则,就会在 String Pool 中添加一个新的字符串,并返回这个新字符串的引用
下面示例中,s1 和 s2 采用 new String() 的方式新建了两个不同字符串,而 s3 和 s4 是通过 s1.intern() 方法取得一个字符串引用。intern() 首先把 s1 引用的字符串放到 String Pool 中,然后返回这个字符串引用。因此 s3 和 s4 引用的是同一个字符串
tring s1 = new String("aaa");
String s2 = new String("aaa");
System.out.println(s1 == s2); // false
String s3 = s1.intern();
String s4 = s1.intern();
System.out.println(s3 == s4); // true
如果是采用 "bbb" 这种字面量的形式创建字符串,会自动地将字符串放入 String Pool 中。
String s5 = "bbb"; String s6 = "bbb"; System.out.println(s5 == s6); // true
String s = new String("xxx");可能创建两个对象也可能创建一个对象。如果常量池中有xxx字符串常量的话,则仅仅在堆中创建一个对象。如果常量池中没有xxx对象,则堆上和常量池都需要创建。
String s = "xxx"这样创建的对象,JVM会直接检查字符串常量池是否已有"xxx"字符串对象,如没有,就分配一个内存存放"xxx",如有了,则直接将字符串常量池中的地址返回给栈。(没有new,没有堆的操作)
在 Java 7 之前,String Pool 被放在运行时常量池中,它属于永久代。而在 Java 7,String Pool 被移到堆中。这是因为永久代的空间有限,在大量使用字符串的场景下会导致 OutOfMemoryError 错误。
String, StringBuffer and StringBuilder的更多相关文章
- String,StringBuffer和StringBuilder源码解析[基于JDK6]
最近指导几位新人,学习了一下String,StringBuffer和StringBuilder类,从反馈的结果来看,总体感觉学习的深度不够,没有读出东西.其实,JDK的源码是越读越有味的.下面总结一下 ...
- String,StringBuffer和StringBuilder的异同
String,StringBuffer和StringBuilder的异同 ...
- String,StringBuffer与StringBuilder
1. String,StringBuffer与StringBuilder的区别 String:存储在常量池中:是不可变的字符序列,任何对String值的改变都会引发新的String对象的生成,因此执行 ...
- Java String, StringBuffer和StringBuilder实例
1- 分层继承2- 可变和不可变的概念3- String3.1- 字符串是一个非常特殊的类3.2- String 字面值 vs. String对象3.3- String的方法3.3.1- length ...
- String,StringBuffer和StringBuilder
String,StringBuffer和StringBuilder分别应该在什么情况下使用? String 是Java的字符串类,其实质上也是用Char类型存储的,但是除了hash属性,其他的属性都声 ...
- String,StringBuffer与StringBuilder的区别??
转自http://blog.csdn.net/rmn190/article/details/1492013 String 字符串常量 StringBuffer 字符串变量(线程安全) StringBu ...
- Java中String,StringBuffer与StringBuilder的差别
String 字符串常量: StringBuffer 字符串变量〈缓冲区〉(线程安全): StringBuilder 字符串变量〈缓冲区〉(非线程安全): 简要的说, String 类型和 Strin ...
- JAVA String,StringBuffer与StringBuilder的区别??
String 字符串常量StringBuffer 字符串变量(线程安全)StringBuilder 字符串变量(非线程安全) 简要的说, String 类型和 StringBuffer 类型的主要性能 ...
- 转 String,StringBuffer与StringBuilder的区别??
String 字符串常量StringBuffer 字符串变量(线程安全)StringBuilder 字符串变量(非线程安全) 简要的说, String 类型和 StringBuffer 类型的主要性能 ...
随机推荐
- C++_标准模板库STL概念介绍3-函数对象
函数对象也叫做函数符(functor). 函数符是可以以函数方式和( )结合使用的任意对象. 包括函数名,指向函数的指针,重载了()运算符的类对象. 可以这样定义一个类: class Linear { ...
- openmpi-3.0.1超线程报错问题
先简单记录一下,虽然还有一些疑惑没有解决. 之前安装openmpi是用的命令安装,版本比较低,mfix并行总出现死锁问题,于是想看看是不是openmpi版本导致,虽然目前还未找到具体原因,但是先记录下 ...
- 大佬的编码建议,让你的代码更pythonic
大佬的编码建议,让你的代码更pythonic Raymond Hettinger是 Python 核心开发者,本文提到的许多特性都是他开发的. 若无例外,本文代码中出现的 colors names d ...
- HDU - 5686-Problem B (递推+高精)
度熊面前有一个全是由1构成的字符串,被称为全1序列.你可以合并任意相邻的两个1,从而形成一个新的序列.对于给定的一个全1序列,请计算根据以上方法,可以构成多少种不同的序列. Input 这里包括多组测 ...
- 挑战程序设计竞赛 P131 区间DP
书上好多题没补 PS.整个DP是根据Q来划分的,dalao的代码就是不一样啊 #include<bits/stdc++.h> #define rep(i,j,k) for(int i=j; ...
- Win10安装MySQL5.7.22解压缩版的方法及手动配置讲解
1.先去MYSQL官网下载安装包,解压放到C盘 2.新建一个my.ini文件放到bin文件夹下面,内容如下,路径对应自己的安装目录: [mysql] # 设置mysql客户端默认字符集 default ...
- Vue-cli 构建项目 的`.vue`组件中, scss中添加背景图路径问题
[解决方法]: 更改build/utils.js文件中的 ExtractTextPlugin 的 options配置. if (options.extract) { return ExtractTex ...
- jquery 方法总结
1. 给列表中 某个 标签添加 点击方法 $(function(){ $(".delete").click(function(){ var href = $(this).att ...
- date +%F时间日期
date +%Y -%m-%d 年月日 date +%T 显示时间 HMS几点几分几秒 -%H 为小时 %w 周几 date -d “-1day” 一天之前 date ...
- oracle 集群RAC搭建(四)--grid部署
安装教程: