0. 前言  

如果一个对象,在它创建完成之后不能再改变它的状态,包括对象内的成员变量、基本数据类型的值等等。那么这个对象就是不可变的。众所周知String类就是不可变的。转载请注明出处为SEU_Calvin的博客

1. String类为什么是不可变的 

首先看一下String类的源码中:

//JDK1.6
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence
{
/**用于存储字符的数组 */
private final char value[];
/** 表示String在这个value数组中的起始位置 */
private final int offset;
/** 字符个数*/
private final int count;
/** 哈希值 */
private int hash; // Default to 0
//...
} //JDK1.7
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
/**用于存储字符的数组 */
private final char value[];
/** 哈希值 */
private int hash; // Default to 0
//....
}

从源码中可以看出,无论是JDK6还是7,虽然内部成员有所改变,但是String类终究是对字符数组的封装。而且value也只是一个引用,它指向一个真正的数组对象。源码中并没有提供value的set方法,因此String类一旦初始化,外部便无法修改,同时value被修饰为 private final,在String类内部也无法改变。所以String对象是不可变的。

我们常用的字符串方法比如substring、replace、replaceAll、toLowerCase等方法,给人的感觉好像是可以改变String内的值,但是这些方法的内部其实在完成逻辑后创建了一个新的String对象并返回。以replace为例,以下是一个简单的例子证明这一点。

String s = "DF2lian";
s = s.replace('F', 'A');
System.out.println("s = " + s); //输出DA2lian String s = "DF2lian";
s.replace('F', 'A');
System.out.println("s = " + s); //输出DF2lian

2. String类真的不可变吗 

从上文可知String的成员变量value是private final修饰的,初始化后不可再改变并且不能再指向其他数组对象。但是value本身是一个引用变量,而不是真正的对象。那么我们就可以通过反射得到String对象中的value属性,进而改变value引用的数组的结构。下面是实例代码:

String s = "DF2lian";
//获取String类中的value字段
Field valueFieldOfString = String.class.getDeclaredField("value");
//改变value属性的访问权限
valueFieldOfString.setAccessible(true);
//获取s对象上的value属性的值
char[] value = (char[]) valueFieldOfString.get(s);
//改变value所引用的数组中某个字符
value[1] = 'R';
System.out.println("s = " + s); //输出DR2lian

Java技术——String类为什么是不可变的的更多相关文章

  1. Java的string类为什么是不可变的

    最流行的Java面试题之一就是:什么是不可变对象(immutable object),不可变对象有什么好处,在什么情况下应该用,或者更具体一些,Java的String类为什么要设成immutable类 ...

  2. java中String类为什么不可变?

    在面试中经常遇到这样的问题:1.什么是不可变对象.不可变对象有什么好处.在什么情景下使用它,或者更具体一点,java的String类为什么要设置成不可变类型? 1.不可变对象,顾名思义就是创建后的对象 ...

  3. 深入分析Java的String类的方法与特点

    字符串是任何编程语言都必须支持的变量类型,有些编程语言是直接提供了原生的变量类型,有些编程语言则使用语法特性以 SDK 的形式提供支持.在Java编程平台中,对字符串的支持使用了后者的形式,就是通过在 ...

  4. java里String类为何被设计为final

    前些天面试遇到一个非常难的关于String的问题,"String为何被设计为不可变的"?类似的问题也有"String为何被设计为final?"个人认为还是前面一 ...

  5. 在java中String类为什么要设计成final?

    大神链接:在java中String类为什么要设计成final? - 程序员 - 知乎 我进行了重新排版,并且更换了其中的一个例子,让我们更好理解. String很多实用的特性,比如说“不可变性”,是工 ...

  6. Java之String类

    String类概述 java.lang.String 类代表字符串.Java程序中所有的字符串文字(例如 "abc" )都可以被看作是实现此类的实例.其实就是说:程序当中所有的双引 ...

  7. Java中String类为什么被设计为final?

    Java中String类为什么被设计为final   首先,String是引用类型,也就是每个字符串都是一个String实例.通过源码可以看到String底层维护了一个byte数组:private f ...

  8. 『Java』String类使用方法

    Java中的字符串 java.lang.String类表示字符串类,Java程序中所有字符串文字都可以看作实现该类的实例. 特点: 字符串不可变:字符串的值在创建后不能在发生改变 public cla ...

  9. Java中String类的方法及说明

    String : 字符串类型 一.      String sc_sub = new String(c,3,2);    //      String sb_copy = new String(sb) ...

随机推荐

  1. EFCore中SQLSERVER 2008 的分页问题

    自SQLSERVER 2012起新增了 Offset Fetch 语法,因此EFCore默认是以此语法生成相应的分页语句的. 如果我们的目标数据库低于 2012,那么EFCore默认生成的语句在执行的 ...

  2. gulp学习。

    安装gulp 安装gulp之前必须先安装node.js,然后在命令行里输入 $ npm install gulp-cli -g (-g 表示全局安装)然后在输入$ gulp -v ,验证,安装完成后再 ...

  3. mssql 监控随笔

    性能监控列表: •    Memory: Pages/sec   ( 从硬盘上读取或写入硬盘的页数(参考值:00~20) •    Physical Disk: % Disk time 或 Physi ...

  4. js-dom-动态创建html标签时,name属性的初始化问题

    当我们动态创建可包含Name属性的元素时,不能简单的使用赋值element.name = "..."来添加其Name, 而必须在创建Element时,使用document.crea ...

  5. eclipse中整合ejb和web工程

    用 Eclipse JEE 版本的话,新建一个 Enterprise Application Project 工程(New --> Java EE --> Enterprise Appli ...

  6. CSS| text文本属性

    注意:一般来说,可以为所有块级元素应用 text-indent,但无法将该属性应用于行内元素,图像之类的替换元素上也无法应用 text-indent 1)  text-indent 取值: 5px/2 ...

  7. python基础学习10----集合

    集合具有无序性,互异性 一.集合的建立 空集合 s=set() s={}#这样默认为是一个空字典 集合内的元素是可哈希的即不可变的数据类型 s={1,2,3,4} s=set([1,2,3,4]) s ...

  8. Resource View Window of Visual Studio

    https://msdn.microsoft.com/en-us/library/d4cfawwc.aspx For the latest documentation on Visual Studio ...

  9. beta冲刺————第五天(5/5=1)

    今天的主要内容是前后端的对接: 通过前几天的对接,我们发现后端传给前端内容是可以很完美的显示出来的,说明文章格式以及一些默认规则都是OK的. 然后就是前端从云服务器上面接受到文章的具体内容,在这一个环 ...

  10. U-Mail:如何实现EDM的个性化和定制化?

    设想一下,一个上班族一天要接到多少垃圾邮件?据媒体报道,目前来往的邮件中,高达95%以上的是垃圾邮件,而且有些垃圾邮件还会故意占据着邮箱的最前列.同时,随着人们接受资讯越来越快捷便利,渠道越来越多,也 ...