Java 中的 String 真的是不可变的吗
转载自 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 真的是不可变的吗相关推荐
- Java中的String为什么是不可变的? -- String源码分析
什么是不可变对象? 众所周知, 在Java中, String类是不可变的.那么到底什么是不可变的对象呢? 可以这样认为:如果一个对象,在它创建完成之后,不能再改变它的状态,那么这个对象就是不可变的.不 ...
- Java中的String为什么是不可变的?
String类是不可变类,一个String对象被创建以后,包含这个对象中的字符串序列是不可改变的.与其问String为什么是不可变的,还不如问String类是如何实现其对象不可变的. 什么是不可变对象 ...
- Java中的String类为什么不可变
1.什么是不可变? java角度来讲就是说成final的. String不可变如下图: 假设给字符串s赋值为abcd,第二次重新赋值为abcdef,这时候并不是在原内存地址上修改数据,而是重新指向一个 ...
- java 字符串是对象吗_解析Java中的String对象的数据类型
解析Java中的String对象的数据类型 2007-06-06 eNet&Ciweek 1. 首先String不属于8种基本数据类型,String是一个对象. 因为对象的默认值是null,所 ...
- Java中关于String类型的10个问题
转载自 Java中关于String类型的10个问题 1. 如何比较两个字符串?用"="还是equals 简单来说,"=="是用来检测俩引用是不是指向内存中的 ...
- c++中string插入一个字符_Java内存管理-探索Java中字符串String(十二)
做一个积极的人 编码.改bug.提升自己 我有一个乐园,面向编程,春暖花开! 一.初识String类 首先JDK API的介绍: public final class String extends O ...
- Java 中的 String、StringBuilder、StringBuffer 的区别
目录 一.是什么? 二.区别是? 1. 运行速度(执行速度) 2. 线程安全 三.小结 四.加餐 一.是什么? String 不可变字符序列 String 是字符串常量,其对象一旦创建之后该对象是不可 ...
- 深入理解Java中的String(原地址https://www.cnblogs.com/xiaoxi/p/6036701.html)
深入理解Java中的String 一.String类 想要了解一个类,最好的办法就是看这个类的实现源代码,来看一下String类的源码: public final class Stringimplem ...
- Java中的String,StringBuilder,StringBuffer三者的区别
最近在学习Java的时候,遇到了这样一个问题,就是String,StringBuilder以及StringBuffer这三个类之间有什么区别呢,自己从网上搜索了一些资料,有所了解了之后在这里整理一下, ...
最新文章
- R语言构建xgboost文本分类模型(bag of words):xgb.cv函数交叉验证确定xgboost模型的最优子树个数、交叉验证获取最优子树之后构建最优xgboost模型并评估模型文本分类效能
- 【Paper】2011_Distributed fault detection for interconnected second-order systems
- qq android2.0,取代QQ?腾讯TIM安卓2.0发布:10GB云盘免费用
- 如何设计真正高性能高并发分布式系统(万字长文)
- c++ map 修改value_干货 | 名企高频考点如何使用map统计字符串各个字符出现的次数...
- 能量视角下的GAN模型:GAN=“挖坑”+“跳坑”
- 5 分钟上手 ECharts
- 1、vue 笔记之 组件
- calendar获取本周一的日期_Java Calendar 获取本周周一和周日代码
- ruby中!!_Ruby反向! 功能
- TestNG配合ant脚本进行单元测试
- HTML5 WebGame开源工具之impactjs
- IDEA设置字体大小没反应解决
- php与jpython-在python中复数怎么表示
- Fiddler证书过期解决
- [转载]在Java应用程序中访问USB设备
- iOS苹果账号/证书/推送证书之我见
- Suspending console(s) (use no_console_suspend to debug) android4.0 OMAP4460
- 电脑中毒,文件夹都变成exe文件怎么办?
- 从“游击队”到“正规军”:虾神成长史
热门文章
- java 变成题_Java 习题8 参考答案及解析
- [Redis6]Redis相关知识介绍
- C++set容器-内置类型指定排序
- 数据结构与索引-- mySql索引诡异事件
- 数据结构与算法--面试必问AVL树原理及实现
- Java连接Mysql数据库警告:Establishing SSL connection without server's identity verification is not recommend
- 深入理解 JVM Class文件格式(六)
- Codeforces Round #716 (Div. 2) D. Cut and Stick 主席树 + 思维
- 牛客题霸 [判断一个链表是否为回文结构] C++题解/答案
- 1148 Werewolf - Simple Version 甲级