【转】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 ...
随机推荐
- 【Codeforces 584C】Marina and Vasya
[链接] 我是链接,点我呀:) [题意] 题意 [题解] 设cnt表示s1和s2不同的字符的个数 如果cnt>2t 因为这cnt个位置肯定至少有一边不同 显然肯定会有一个f(s,S)的值大于t的 ...
- HDU 4451 容斥原理
题目大意: n件衣服,m条裤子,k双鞋子进行搭配 妈妈指明了哪些衣服和裤子不能搭配,哪些裤子和鞋子不能搭配,问最后有几种搭配方法 先假设都能搭配 n*m*k 每次遇到衣服和裤子不能搭的,就要减一次k, ...
- NOIP1999 邮票面值设计
题目描述 Description 给定一个信封,最多只允许粘贴N张邮票,计算在给定K(N+K≤40)种邮票的情况下(假定所有的邮票数量都足够),如何设计邮票的面值,能得到最大值MAX,使在1-MAX之 ...
- [bzoj 1005][HNOI 2008]明明的烦恼(prufer数列+排列组合)
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1005 分析: 首先prufer数列:http://baike.baidu.com/view/1 ...
- Spring + quartz实现定时发送邮件功能
在做具体的系统管理时,往往会有每隔一段时间发给用户一些邮件的业务,现在参考的网上的大部分代码,写下了我自己的代码. 在ApplicationContext.xml的内容如下: <?xml ver ...
- 洛谷 P3063 [USACO12DEC]牛奶的路由Milk Routing
P3063 [USACO12DEC]牛奶的路由Milk Routing 题目背景 征求翻译.如果你能提供翻译或者题意简述,请直接发讨论,感谢你的贡献. 题目描述 Farmer John's farm ...
- - > 强烈推荐!!!
学长的微博总是能帮我们解决很多问题QAQ,超有用的: http://blog.csdn.net/cax1165/article/category/6294316/6
- 【剑指offer】合并两有序单链表
转载请注明出处:http://blog.csdn.net/ns_code/article/details/25739727 九度OJ上AC,採用归并的思想递归实现. 题目描写叙述: 输入两个单调递增的 ...
- Java进程堆外内存(off heap)大小
一.使用ByteBuffer.allocateDirect分配的off heap内存大小 本机进程 在Jvisualvm中安装 Mbeans插件.然后查看java.nio/BufferPool/dir ...
- 学习C语言,困难吗?
要说计算机如今什么最火.无异于网络.看看各大计算机站点,满眼尽是网络project师,什么IP啊,路由啊,虚拟机啊,总之,操作性的计算机技能牢牢占领了半壁江山. 这些技巧当然重要.可是 ...