String不可变性
今天分析一下String,String有很多实用的特性,比如说“不可变性”,是工程师精心设计的艺术品。用final就是拒绝继承,防止内部属性或方法被破坏。
一,什么是不可变?
String不可变很简单,如图,给一个已有字符串“abcd”,第二次赋值为“abcde”,不是在原内存地址上修改数据,而是重新指向一个新对象,新地址。

二,String为什么不可变?
翻看IDK源码,String类前几行是这样写的:
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[]; /** Cache the hash code for the string */
private int hash; // Default to 0
首先String是被final修饰,这说明String不可被继承。下面String的主要字段value是个char[]数组,并且被final修饰。final修饰的字段创建后就不可改变。但是value是引用类型,用final修饰,只能说明value的引用地址不可变,但是挡不住char[]数组本身可变的事实。注意黑体的这段话,正如分析final关键字时所说,对于基本类型,final使数值恒定不变;而用于对象引用,final使引用恒定不变。一旦引用被初始化指向一个对象,就无法再把它改为指向另一个对象。然而,对象其自身却是可以被修改的。
final int[] value={2,3,4};
value[2]=100; //这时候数组里已经是{2,3,100}
所以String不可变,关键是因为SUN公司的工程师,在后面所有String的方法里很小心的没有去动Array里的元素,没有暴露内部成员字段。private final char value[]这一句里,private的私有访问权限的作用比final都大。而且工程师还很小心地把整个String类设成final禁止继承,避免被其他人继承后破坏。所以String不可变的关键在底层的实现,而不是一个final。
三,不可变的好处
1,字符串常量池的需要。
字符串常量池在方法区是一块特殊的存储区域。当字符串已经在常量池中,此时创造字符串时,直接返回已存在字符串的引用,而不是重新创造一个String对象。
String string1 = "abcd";
String string2 = "abcd";

2,快速获取哈希码。
String的哈希码在java中经常被使用。例如,在HashMap或者HashSet中。不可变确保了哈希码总是相同的。那就意味着每次在使用时不需要重新计算哈希码,这样更高效。
private int hash;
3,不可变对象是线程安全的。
因为不可变对象并不能被改变,因此它们能放心地在多线程中使用,这就使得不必另外做同步。
四,比较(String),toString()和String.valueOf()的区别
1,(String),这是标准的类型转换,将其他类型转成String类型。使用这种方法时,需要注意的是类型必须能转成String类型,因此最好用instanceof做个类型检查,以判断是否可以转换。否则容易抛出CalssCastException异常。
2,toString(),在这种使用方法中,因为java.lang.Object类里已有public方法.toString(),所以对任何严格意义上的java对象都可以调用此方法。但在使用时要注意,必须保证object不是null值,否则将抛出NullPointerException异常,也可以在子类中重写toString()方法。
3,String.valueOf(),此方法不会报空指针异常,弥补了toString()的不足。但是需要注意,null返回的是字符串“null”。
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
参考:https://www.zhihu.com/question/31345592
String不可变性的更多相关文章
- java基础解析系列(九)---String不可变性分析
java基础解析系列(九)---String不可变性分析 目录 java基础解析系列(一)---String.StringBuffer.StringBuilder java基础解析系列(二)---In ...
- 记一次愚蠢的经历--String不可变性
前言 只有光头才能变强. 文本已收录至我的GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3y 记录一次在写代码时愚蠢的操作,本文涉及到的知识点:S ...
- 浅析String不可变性
在所有编程语言领域,我想字符串应该是地球上最常用的表达手段了吧. 在java的世界里,String是作为类出现的,核心的一个域就是一个char数组,内部就是通过维护一个不可变的char数组,来向外部输 ...
- 一、图解Java中String不可变性
这里有一堆例子来说明Java的String的不可变性. 1.声明一个String String s = "abcd"; s 变量保存string对象的引用,下面的箭头解释成保存了哪 ...
- Java基础:String不可变性和final修饰
转载请注明出处: jiq•钦's technical Blog - 季义钦 String的不可变性 Java规定String是不可变的(immutable).事实上这个不可变具备两层含义: 1 内容不 ...
- Java中String类型的不可变性和驻留池
一 基本概念 可变类和不可变类(Mutable and Immutable Objects)的初步定义: 可变类:当获得这个类的一个实例引用时,可以改变这个实例的内容. 不可变类:不可变类的实例一但创 ...
- 【JDK源码分析】String的存储区与不可变性(转)
// ... literals are interned by the compiler // and thus refer to the same object String s1 = " ...
- 图解String类型的不可变性及其原因
1.String的不可变性 String s="abcd": 上面的语句定义了一个字符串变量s.该变量指向字符串"abcd",当初始化变量s时,会在堆中为s非配 ...
- String、StringBuilder和StringBuffer
1.string不可变性 java的docs有这样一句话:Strings are constant; their values cannot be changed after they are cre ...
随机推荐
- Centos7.5 在桌面创建AndroidStudio快捷方式
Centos7 在桌面创建AndroidStudio快捷方式 前言 最近安装了Centos7,打算将开发平台转移到Linux下,安装好AndroidStudio后,桌面没有快捷方式有些不习惯,随自己创 ...
- 本地Gradle配置方法,免去长时间的更新同步等待
通常gradle项目在gradle\wrapper\gradle-wrapper.properties中配置在线gradle: distributionBase=GRADLE_USER_HOME di ...
- hibernate_04_hbm.xml介绍
先贴上类文件Students.hbm.xml <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC & ...
- Percona Xtrabackup导出/导入单表
默认情况下,InnoDB表不能通过直接复制表文件的方式在mysql服务器之间进行移植,即便使用了innodb_file_per_table选项.而使用Xtrabackup工具可以实现此种功能,不过,此 ...
- java的优先队列注意事项
在C++语言中,使用优先队列,直接构建一个lambda表达式,使用一个匿名函数指针.java比较函数的返回值不是bool型,只能是整型. 内部对应的C++匿名函数: // 匿名Comparator实现 ...
- 请不要继续使用VC6.0了!
很多次和身边的同学交流,帮助同学修改代码,互相分享经验,却发现同学们依然在使用老旧的VC6.0作为编程学习的软件,不由得喊出:“请不要继续使用VC6.0了!”. VC6.0作为当年最好的IDE(集成开 ...
- uni-app强大的前端框架,h5,原生app(两大系统),微信小程序
最近发现一款强大的前端框架,它叫uni-app 这是一款通用的框架可以打包app,h5,微信小程序, 说说要弄这个工具需要会那些技能吧, 要熟悉vue,微信小程序.这样这个框架用的就是很快上手了 模块 ...
- 触发a标签
var aLink = document.createElement("a"); aLink.download = ''; aLink.href = url; if (docume ...
- Microsoft Visual Studio 常用快捷键总结
table tr:nth-child(odd){ background: #FFFFCC; } table tr:nth-child(even){ background: #FFFF99; } Mic ...
- SPLAY or SPALY ?
写在前面: 由我们可爱的Daniel Sleator和Robert Tarjan提出的一种数据结构,平衡树的一种,本质是二叉树. 至于到底是splay还是spaly,我认为可能splay更对一些 毕竟 ...