转载自   Java 中的 String 真的是不可变的吗

我们都知道 Java 中的 String 类的设计是不可变的,来看下 String 类的源码。

public final class Stringimplements 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); // Pythonstr = "Java";
System.out.println(str); // Javastr = 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 PythonField 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 类的不可变设计原则,会造成一些安全问题。

Java 中的 String 真的是不可变的吗相关推荐

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

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

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

    String类是不可变类,一个String对象被创建以后,包含这个对象中的字符串序列是不可改变的.与其问String为什么是不可变的,还不如问String类是如何实现其对象不可变的. 什么是不可变对象 ...

  3. Java中的String类为什么不可变

    1.什么是不可变? java角度来讲就是说成final的. String不可变如下图: 假设给字符串s赋值为abcd,第二次重新赋值为abcdef,这时候并不是在原内存地址上修改数据,而是重新指向一个 ...

  4. java 字符串是对象吗_解析Java中的String对象的数据类型

    解析Java中的String对象的数据类型 2007-06-06 eNet&Ciweek 1. 首先String不属于8种基本数据类型,String是一个对象. 因为对象的默认值是null,所 ...

  5. Java中关于String类型的10个问题

    转载自   Java中关于String类型的10个问题 1. 如何比较两个字符串?用"="还是equals 简单来说,"=="是用来检测俩引用是不是指向内存中的 ...

  6. c++中string插入一个字符_Java内存管理-探索Java中字符串String(十二)

    做一个积极的人 编码.改bug.提升自己 我有一个乐园,面向编程,春暖花开! 一.初识String类 首先JDK API的介绍: public final class String extends O ...

  7. Java 中的 String、StringBuilder、StringBuffer 的区别

    目录 一.是什么? 二.区别是? 1. 运行速度(执行速度) 2. 线程安全 三.小结 四.加餐 一.是什么? String 不可变字符序列 String 是字符串常量,其对象一旦创建之后该对象是不可 ...

  8. 深入理解Java中的String(原地址https://www.cnblogs.com/xiaoxi/p/6036701.html)

    深入理解Java中的String 一.String类 想要了解一个类,最好的办法就是看这个类的实现源代码,来看一下String类的源码: public final class Stringimplem ...

  9. Java中的String,StringBuilder,StringBuffer三者的区别

    最近在学习Java的时候,遇到了这样一个问题,就是String,StringBuilder以及StringBuffer这三个类之间有什么区别呢,自己从网上搜索了一些资料,有所了解了之后在这里整理一下, ...

最新文章

  1. R语言构建xgboost文本分类模型(bag of words):xgb.cv函数交叉验证确定xgboost模型的最优子树个数、交叉验证获取最优子树之后构建最优xgboost模型并评估模型文本分类效能
  2. 【Paper】2011_Distributed fault detection for interconnected second-order systems
  3. qq android2.0,取代QQ?腾讯TIM安卓2.0发布:10GB云盘免费用
  4. 如何设计真正高性能高并发分布式系统(万字长文)
  5. c++ map 修改value_干货 | 名企高频考点如何使用map统计字符串各个字符出现的次数...
  6. 能量视角下的GAN模型:GAN=“挖坑”+“跳坑”
  7. 5 分钟上手 ECharts
  8. 1、vue 笔记之 组件
  9. calendar获取本周一的日期_Java Calendar 获取本周周一和周日代码
  10. ruby中!!_Ruby反向! 功能
  11. TestNG配合ant脚本进行单元测试
  12. HTML5 WebGame开源工具之impactjs
  13. IDEA设置字体大小没反应解决
  14. php与jpython-在python中复数怎么表示
  15. Fiddler证书过期解决
  16. [转载]在Java应用程序中访问USB设备
  17. iOS苹果账号/证书/推送证书之我见
  18. Suspending console(s) (use no_console_suspend to debug) android4.0 OMAP4460
  19. 电脑中毒,文件夹都变成exe文件怎么办?
  20. 从“游击队”到“正规军”:虾神成长史

热门文章

  1. java 变成题_Java 习题8 参考答案及解析
  2. [Redis6]Redis相关知识介绍
  3. C++set容器-内置类型指定排序
  4. 数据结构与索引-- mySql索引诡异事件
  5. 数据结构与算法--面试必问AVL树原理及实现
  6. Java连接Mysql数据库警告:Establishing SSL connection without server's identity verification is not recommend
  7. 深入理解 JVM Class文件格式(六)
  8. Codeforces Round #716 (Div. 2) D. Cut and Stick 主席树 + 思维
  9. 牛客题霸 [判断一个链表是否为回文结构] C++题解/答案
  10. 1148 Werewolf - Simple Version 甲级