我们都知道 Java 中的 String 类的设计是不可变的,来看下 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 不能被继承。其值 value 也就是对字符数组的封装,即 char[],其值被定义成 private final 的,说明不能通过外界修改,即不可变。

String 真的 "不可变 " 吗?

来看下面这个例子。

String str = "Python";
System.out.println(str); // Python str = "Java";
System.out.println(str); // Java str = str.substring(1);
System.out.println(str); // ava

你有可能会问:str 不是由 Python 变成 Java 了吗?然后通过 substring 方法变成 ava 了吗?

这其实是初学者的一个误区,从上面看 String 的结构可以得知字符串是由字符数组构成的,str 只是一个引用而已,第一次引用了 "Python",后面变成了 "Java",而 substring 也是用 Arrays.copyOfRange 方法重新复制字符数组构造了一个新的字符串。

所以说,这里的字符串并不是可变,只是变更了字符串引用。

关于 substring 在 JDK 各个版本的差异可以看这篇文章《注意:字符串substring方法在jkd6,7,8中的差异》,也可以去看 substring 的各个版本的源码。

String 真的真的真的 "不可变 " 吗?

上面的例子肯定是不可变的,下面这个就尴尬了。

String str = "Hello Python";
System.out.println(str); // Hello Python Field field = String.class.getDeclaredField("value");
field.setAccessible(true); char[] value = (char[])field.get(str);
value[6] = 'J';
value[7] = 'a';
value[8] = 'v';
value[9] = 'a';
value[10] = '!';
value[11] = '!';
System.out.println(str); // Hello Java!!

通过反射,我们改变了底层的字符数组的值,实现了字符串的 “不可变” 性,这是一种骚操作,不建议这么使用,违反了 Java 对 String 类的不可变设计原则,会造成一些安全问题。

是不是又涨姿势了?分享给你的朋友们吧!

更多干货推荐

1.史上最强 Java 中高级面试题整理

2.史上最强 Spring Boot & Cloud 教程整理

3.史上最强架构设计分布式技术干货整理

更多请扫描下方的二维码关注我们的微信公众号,干货每日推送!

Java 中的 String 真的是不可变吗?的更多相关文章

  1. Java中的String为什么是不可变的?

    转载:http://blog.csdn.net/zhangjg_blog/article/details/18319521 什么是不可变对象? 众所周知, 在Java中, String类是不可变的.那 ...

  2. Java中的String为什么是不可变的? -- String源码分析

    众所周知, 在Java中, String类是不可变的.那么到底什么是不可变的对象呢? 可以这样认为:如果一个对象,在它创建完成之后,不能再改变它的状态,那么这个对象就是不可变的.不能改变状态的意思是, ...

  3. Java中的String为什么是不可变的? — String源码分析

    原文地址:http://www.importnew.com/16817.html 什么是不可变对象? 众所周知, 在Java中, String类是不可变的.那么到底什么是不可变的对象呢? 可以这样认为 ...

  4. 【转】Java中的String为什么是不可变的? -- String源码分析

    什么是不可变对象? 众所周知, 在Java中, String类是不可变的.那么到底什么是不可变的对象呢? 可以这样认为:如果一个对象,在它创建完成之后,不能再改变它的状态,那么这个对象就是不可变的.不 ...

  5. (转)Java中的String为什么是不可变的? -- String源码分析

    背景:被问到很基础的知识点  string  自己答的很模糊 Java中的String为什么是不可变的? -- String源码分析 ps:最好去阅读原文 Java中的String为什么是不可变的 什 ...

  6. (转)Java中的String为什么是不可变的

    转自:http://www.importnew.com/7440.html String是所有语言中最常用的一个类.我们知道在Java中,String是不可变的.final的.Java在运行时也保存了 ...

  7. 为什么Java中的String类是不可变的?

    String类是Java中的一个不可变类(immutable class). 简单来说,不可变类就是实例在被创建之后不可修改. 在<Effective Java> Item 15 中提到了 ...

  8. Java中的String真的无法修改吗

    Java中String一旦赋值将无法修改,每次对String值的修改都是返回新的String. 如何在不创建新的String对象的情况下,对String的值进行修改呢? String类中的包含一个字段 ...

  9. Java基础知识强化101:Java 中的 String对象真的不可变吗 ?

    1. 什么是不可变对象?       众所周知, 在Java中, String类是不可变的.那么到底什么是不可变的对象呢? 可以这样认为:如果一个对象,在它创建完成之后,不能再改变它的状态,那么这个对 ...

随机推荐

  1. new delate he typedef的含义

    new:        new 类型[初值] 如: new int ;                                     //开辟一个存放整数的存储空间,返回一个指向该存储空间的 ...

  2. instanceof简单用法

    语法: 对象 instanceof 类: 含义:如果这个对象时这个类或者这个类的子类的实例化,那么结果及时ture, 否则 false. 常常用来判断一个类是否是某个类的子类,以此判断A类是否继承或者 ...

  3. Filezilla server配置FTP服务器中的各种问题与解决方法

    转至;https://www.jb51.net/article/122171.htm 安装文件以及补丁下载 公司很多资料需要通过ftp上传,那么就需要配置一个FTP服务器,找了一台Windows服务器 ...

  4. PackageManagerService 学习记录 基于7.1.1源码

    参考: http://blog.csdn.net/innost/article/details/47253179 http://blog.csdn.net/gaugamela/article/deta ...

  5. mysql时间戳转换

    数据表中time是时间戳格式,转化成正常的时间格式 SELECT id,TIME,FROM_UNIXTIME(TIME,'%Y-%m-%d %H:%m:%S'),incline_id FROM inc ...

  6. .gitignore语法

    没嘛用 “#”表示注释 “!”表示取消忽略 空行不作匹配 若匹配语句中无“/ ” ,便将其视为一个 glob匹配,如'abc'可以匹配 ' abc' , 'cd/abc' , 'ef/abcde.tx ...

  7. Js2WordCloud 词云用法

    1.引入 npm 安装: npm install js2wordcloud --save 通过script引入: <script src="dist/js2wordcloud.min. ...

  8. Promise实战AJAX封装

    一.利用Promise的知识,对最开始的ajax的例子进行一个简单的封装: var url = 'xxx'; // 封装一个get请求的方法 function request(url){ return ...

  9. mysql 8 windows 下安装

    1.下载 mysql8 需要下载 window的 zip版本 2.解压 D:\software\mysql\mysql-8.0.16-winx64 2.在这个目录下创建一个 my.ini 的文件 [m ...

  10. numpy 库简单使用

    numpy 库简单使用 一.numpy库简介 Python标准库中提供了一个array类型,用于保存数组类型的数据,然而这个类型不支持多维数据,不适合数值运算.作为Python的第三方库numpy便有 ...