【转】Java中的String为什么是不可变的? -- String源码分析
什么是不可变对象?
众所周知, 在Java中, String类是不可变的。那么到底什么是不可变的对象呢? 可以这样认为:如果一个对象,在它创建完成之后,不能再改变它的状态,那么这个对象就是不可变的。不能改变状态的意思是,不能改变对象内的成员变量,包括基本数据类型的值不能改变,引用类型的变量不能指向其他的对象,引用类型指向的对象的状态也不能改变。
区分对象和对象的引用
String s = "ABCabc";
System.out.println("s = " + s); s = "123456";
System.out.println("s = " + s);
s = 123456
为什么String对象是不可变的?
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence
{
/** The value is used for character storage. */
private final char value[]; /** The offset is the first index of the storage that is used. */
private final int offset; /** The count is the number of characters in the String. */
private final int count; /** Cache the hash code for the string */
private int hash; // Default to 0
}
在JDK1.7中,String类做了一些改动,主要是改变了substring方法执行时的行为,这和本文的主题不相关。JDK1.7中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 a = "ABCabc";
System.out.println("a = " + a);
a = a.replace('A', 'a');
System.out.println("a = " + a);
a = aBCabc
String ss = "123456";
System.out.println("ss = " + ss);
ss.replace('1', '0');
System.out.println("ss = " + ss);
ss = 123456
String对象真的不可变吗?
import java.lang.reflect.Field;
public class Knight {
public static void main(String[] args)
throws NoSuchFieldException, SecurityException,
IllegalArgumentException, IllegalAccessException
{
//创建字符串"Hello World", 并赋给引用s
String s = "Hello World";
System.out.println("s = " + s); //Hello World
//获取String类中的value字段
Field valueFieldOfString = String.class.getDeclaredField("value");
//改变value属性的访问权限
valueFieldOfString.setAccessible(true);
//获取s对象上的value属性的值
char[] value = (char[]) valueFieldOfString.get(s);
//改变value所引用的数组中的第5个字符
value[5] = '_';
System.out.println("s = " + s); //Hello_World
}
}
s = Hello_World
【转】Java中的String为什么是不可变的? -- String源码分析的更多相关文章
- Java并发编程笔记之Unsafe类和LockSupport类源码分析
一.Unsafe类的源码分析 JDK的rt.jar包中的Unsafe类提供了硬件级别的原子操作,Unsafe里面的方法都是native方法,通过使用JNI的方式来访问本地C++实现库. rt.jar ...
- java 集合与数组的互转方法,与源码分析
前言 java数组与集合需要互相转换的场景非常多,但是运用不好还是容易抛出UnSupportedOperationException.下面讲解一下互转的方法,以及结合源码分异常产生的原因 集合转数组 ...
- SqlAlchemy 中操作数据库时session和scoped_session的区别(源码分析)
原生session: from sqlalchemy.orm import sessionmaker from sqlalchemy import create_engine from sqlalch ...
- Java 自动拆箱 装箱 包装类的缓存问题--结合源码分析
都0202 了 java 1.8 已经是主流 自动装箱 .拆箱已经很普遍使用了,那么有时候是不是会遇到坑呢? 我们先来看一段代码: public class TestWraperClass { pub ...
- Java I/O系列(二)ByteArrayInputStream与ByteArrayOutputStream源码分析及理解
1. ByteArrayInputStream 定义 继承了InputStream,数据源是内置的byte数组buf,那read ()方法的使命(读取一个个字节出来),在ByteArrayInputS ...
- netty中的发动机--EventLoop及其实现类NioEventLoop的源码分析
EventLoop 在之前介绍Bootstrap的初始化以及启动过程时,我们多次接触了NioEventLoopGroup这个类,关于这个类的理解,还需要了解netty的线程模型.NioEventLoo ...
- Java I/O系列(一)InputStream与OutputStream源码分析及理解
1. InputStream 定义 字节输入流,是一个抽象类,核心是通过read()方法,从数据源中读取一个个字节出来,另有skip,mark功能 核心源码理解 源码: public abstract ...
- Disruptor中shutdown方法失效,及产生的不确定性源码分析
版权声明:原创作品,谢绝转载!否则将追究法律责任. Disruptor框架是一个优秀的并发框架,利用RingBuffer中的预分配内存实现内存的可重复利用,降低了GC的频率. 具体关于Disrupto ...
- Java并发基础:了解无锁CAS就从源码分析
https://segmentfault.com/a/1190000015881923
- 死磕 java并发包之AtomicStampedReference源码分析(ABA问题详解)
问题 (1)什么是ABA? (2)ABA的危害? (3)ABA的解决方法? (4)AtomicStampedReference是什么? (5)AtomicStampedReference是怎么解决AB ...
随机推荐
- Java基础学习总结(83)——Java泛型总结
1. 什么是泛型? 泛型(Generic type 或者 generics)是对 Java 语言的类型系统的一种扩展,以支持创建可以按类型进行参数化的类.可以把类型参数看作是使用参数化类型时指定的类型 ...
- hadoop full cluster 改为伪分布
https://hadoop.apache.org/docs/r2.7.6/hadoop-project-dist/hadoop-common/SingleCluster.html#Pseudo-Di ...
- [luoguP3565] [POI2014]HOT-Hotels(dfs)
传送门 三点在树上距离相等的情况只有一种,就是以某一个点为中心,三个点到这个点的距离相等. 所以直接枚举每个点作为中心,dfs这个中心的子树,根据乘法原理统计答案即可. 时间复杂度 O(n2) (n ...
- [Usaco2015 dec]Max Flow
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 204 Solved: 129[Submit][Status][Discuss] Descriptio ...
- poj 3074
题意:解数独 分析: 完整的数独有四个充要条件: 1.每个格子都有填数字 2.每列都有1~9中的每个数字 3.每行都有1~9中的每个数字 4.每个9宫格都有1~9中的每个数字 可以转化成精确覆盖问题. ...
- [bzoj1572][Usaco2009 Open]工作安排Job_贪心_堆
工作安排 Job bzoj-1572 Usaco-2009 Open 题目大意:题目链接. 注释:略. 想法: 我们将任务按照截止时间排序,枚举任务的同时顺便记录出已经做了多少任务(当前时间). 对于 ...
- springboot启动mybatis
初期开发了generator可以根据表结果自动生产实体类.配置文件和dao层代码,可以减轻一部分开发量:后期也进行了大量的优化可以使用注解了,自动管理dao层和配置文件等,发展到最顶端就是今天要讲的这 ...
- cocos2D(七)---- CCScene
CCScene普通情况是游戏里面的根节点.称之为"场景",执行游戏时须要通过CCDirector启动第一个场景. 当然,游戏略微复杂一点的话.可能会包括非常多个场景,这就涉及到场景 ...
- 【独立开发人员er Cocos2d-x实战 009】Cocos2dx 菜单项CCMenu使用
Cocos2dx中的菜单用CCMenu/Menu类来实现.该类是一个容器.用来装载各种菜单项,用于菜单项能够是图片.系统字体等. 理论就不说了.先上代码: CCMenuItemToggle* item ...
- swift 2.0 语法 常量变量
import UIKit /*: 常量变量 * 常量: let * 变量: var 完整格式: * 修饰符(let/var) 常量/变量名称: 数据类型 */ let number: Int var ...