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 ...
随机推荐
- A题时遇到的一些技巧
这篇主要是讲刷题时候遇到的一些技巧,该篇保持持续更新状态.. 1.求数组的长度:int a[]={,,,}; int n = sizeof(a)/sizeof(a[0]) 2.求想上取整,例如7/3 ...
- 【Oracle】rollup函数
当我们在做报表统计的时候,很多时候需要用到‘合计’这个功能,比如我们想得到如下格式的报表: 这张表是按照deptno分组,然后按照deptno分组合计.rollup函数可以完美的解决这个问题. 1.建 ...
- Deutsch lernen (04)
1. streng a. 严厉的,严格的 streng gegen sich selbst und gegen andere sein streng auf Ordnung halten 2. ver ...
- ROS:使用ubuntuKylin17.04安装ROS赤xi龟
使用ubuntuKylin17.04安装 参考了此篇文章:SLAM: Ubuntu16.04安装ROS-kinetic 重复官方链接的步骤也没有成功. 此后发现4.10的内核,不能使用Kinetic. ...
- 读书笔记「Python编程:从入门到实践」_7.用户输入和while循环
7.1 函数input()的工作原理 函数input() 让程序暂停运行,等待用户输入一些文本.获取用户输入后,Python将其存储在一个变量中,以方便你使用. message = input(&qu ...
- nginx_安装测试
首先安装环境: [root@local nginx-1.9.14]# yum install gcc-c++ pcre pcre-devel zlib zlib-devel openssl op ...
- Java导出Excel(附完整源码)
导出excel是咱Java开发的必备技能啦,之前项目有这个功能,现在将其独立出来,分享一下.所用技术就是SpringBoot,然后是MVC架构模式.废话不多说,直接上代码了,源码点末尾链接就可以下载. ...
- JAVA版CORBA程序
1.题目分析题目1.Java版CORBA程序1——HelloWorld编写实现显示“Hello,World!+班级+中文姓名”字符串.题目2.JAVA版CORBA程序2——Counter编写实现连加. ...
- 解决vcenter 6.0 vcsa安装插件时报错的问题
在安装vCenter 6.0 vsca的时候,安装插件到第二个的时候,会报出一个windows installer的错误.需要联系软件管理员或者技术支持的一个error. 经过多次的测试,我终于找到了 ...
- Java-Class-Test:Test-1
ylbtech-Java-Class-Test:Test-1 1.返回顶部 1.1. package com.ylbtech.api; import com.y;btech.WxApiApplicat ...