今天分析一下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. [原创]Linux(CentOS)下安装mongodb

    和上一篇一样,装个这个踩了无数个坑…… 1.下载 wget http://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel55-3.2.12.tgz ...

  2. 关于angular双向绑定的一个问题,百度无果,还请帮忙解惑。

    用了一段时间anjular蛮好用的.其实用的功能不多.主要用于列表数据绑定以及一些简单效果的绑定,但是最近出现一个现象,百度无果,居然没有人遇到.现在描述一下,截图不方便,希望有人解惑. 列表ng-r ...

  3. JDK自带工具

    工具名称 描述 appletviewer.exe 用于运行并浏览applet小程序. apt.exe 注解处理工具(Annotation Processing Tool),主要用于注解处理. extc ...

  4. VC维与DNN的Boundary

    原文链接:解读机器学习基础概念:VC维来去 作者:vincentyao 目录: 说说历史 Hoeffding不等式 Connection to Learning 学习可行的两个核心条件 Effecti ...

  5. MySQL创建临时表

    drop TEMPORARY table if EXISTS temp_table; create TEMPORARY table temp_table( id int not null, usern ...

  6. 理解Linux CPU负载和 CPU使用率

    CPU负载和 CPU使用率 这两个从一定程度上都可以反映一台机器的繁忙程度. cpu使用率反映的是当前cpu的繁忙程度,忽高忽低的原因在于占用cpu处理时间的进程可能处于io等待状态但却还未释放进入w ...

  7. [MySQL优化案例]系列 — 分页优化

    通常,我们会采用ORDER BY LIMIT start, offset 的方式来进行分页查询.例如下面这个SQL: SELECT * FROM `t1` WHERE ftype=1 ORDER BY ...

  8. Dell R720修改远程管理口的密码

    今天有个客户需要通过远程管理口来查看系统事件日志,但是他们把初始密码改过并且还给忘记了.后来我决定进操作系统(cent os)进行修改.整个过程很简单,进入系统后只需要三个步骤就解决问题了 1.安装软 ...

  9. 如何制作一个类似jquery插件的vue插件

    vue拿来写插件,会不会太那啥? 请跟我念,"不会,符合业务需求才是你的老板最想要的." 如何封装一个可以全局调用的vue插件 其原理其实相当简单,通过new Vue(vueCom ...

  10. How many integers can you find

    How many integers can you find Time Limit: 12000/5000 MS (Java/Others)    Memory Limit: 65536/32768 ...