今天分析一下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不可变性的更多相关文章

  1. java基础解析系列(九)---String不可变性分析

    java基础解析系列(九)---String不可变性分析 目录 java基础解析系列(一)---String.StringBuffer.StringBuilder java基础解析系列(二)---In ...

  2. 记一次愚蠢的经历--String不可变性

    前言 只有光头才能变强. 文本已收录至我的GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3y 记录一次在写代码时愚蠢的操作,本文涉及到的知识点:S ...

  3. 浅析String不可变性

    在所有编程语言领域,我想字符串应该是地球上最常用的表达手段了吧. 在java的世界里,String是作为类出现的,核心的一个域就是一个char数组,内部就是通过维护一个不可变的char数组,来向外部输 ...

  4. 一、图解Java中String不可变性

    这里有一堆例子来说明Java的String的不可变性. 1.声明一个String String s = "abcd"; s 变量保存string对象的引用,下面的箭头解释成保存了哪 ...

  5. Java基础:String不可变性和final修饰

    转载请注明出处: jiq•钦's technical Blog - 季义钦 String的不可变性 Java规定String是不可变的(immutable).事实上这个不可变具备两层含义: 1 内容不 ...

  6. Java中String类型的不可变性和驻留池

    一 基本概念 可变类和不可变类(Mutable and Immutable Objects)的初步定义: 可变类:当获得这个类的一个实例引用时,可以改变这个实例的内容. 不可变类:不可变类的实例一但创 ...

  7. 【JDK源码分析】String的存储区与不可变性(转)

    // ... literals are interned by the compiler // and thus refer to the same object String s1 = " ...

  8. 图解String类型的不可变性及其原因

    1.String的不可变性 String s="abcd": 上面的语句定义了一个字符串变量s.该变量指向字符串"abcd",当初始化变量s时,会在堆中为s非配 ...

  9. String、StringBuilder和StringBuffer

    1.string不可变性 java的docs有这样一句话:Strings are constant; their values cannot be changed after they are cre ...

随机推荐

  1. 《java数据结构与算法》系列之“快速排序"

    部门没人了,公司动作好快...算了,不想了!还是学知识吧,只有它不会让自己失望. 继续我的算法学习,快速排序是应用很广的算法,看了一早上才看懂些,感觉比冒泡之类的难理解,可能主要是递归那块自己不是很理 ...

  2. 存档:Telerik Test Studio的摸索笔记

    http://www.51testing.com/?uid-170604-action-spacelist-starttime-1328025600-endtime-1330531200 http:/ ...

  3. SLAM: Orb_SLAM中的ORB特征

    原文链接:什么是ORB 关于Orb特征的获取:参考 最新版的OpenCV中新增加的ORB特征的使用 ORB是是ORiented Brief 的简称,对Brief的特定性质进行了改进. ORB的描述在下 ...

  4. beetl模板入门例子

    加入maven依赖 <dependency> <groupId>org.beetl</groupId> <artifactId>beetl-core&l ...

  5. Apex语言(六)数组

    1.数组 数组能保存多个数据,每一个数据称为数组元素,元素的个数称为数组的长度. 数组元素的类型必须相同,元素的类型就是数组的类型. 数组元素在数组中都有一个编号,称为数组下标.下标从0开始编号,通过 ...

  6. Linux删除大于/小于固定大小的文件等

    删除目录下大小为0的文件 rm -f 删除当前目录下面所有 test 文件夹下面的文件 find ./ -name "test" -type d -exec rm -rf {} ; ...

  7. Idea中修改servlet模板

    1.点击左上角的File: Setting --> Editor --> File and Code Templates --> Other --> web -->Ser ...

  8. Noip 2015 练习

    子串 传送门 Solution \(f[i][j][k]\)表示A到i,B到j第k个子串的答案 \(g[i][j][k]\)表示A到i,B到j第k个子串且A[i]一定使用 \(g[i][j][k]=( ...

  9. Intro.js 分步向导插件使用方法

    简介 为您的网站和项目提供一步一步的.更好的介绍 Intro.js 目前兼容 Firefox.Chrome 和 IE8,不兼容 IE6 和 IE7,后续版本将会提供更好的兼容. 在线演示及下载 在线演 ...

  10. ASP.NET Core多平台部署 (Windows Server+IIS与CentOS 7+Nginx)

    一,Windows Server+IIS部署 1,安装配置IIS,这个应该都不用多说了,教程一堆 2,下载安装.NET Core Runtime 与 .NET Core SDK,下载请点击下载地址,如 ...