原文网址:
String真的不可变吗?简介
String类使用char value[]来存字符数据,它的类型为:private final char value[];
看上去它是不可更改的,因为是final类型。注意:final只是表示不能指向其他地址,它里边的内容是可以更改的。
结论:String是可以更改的,使用反射,value.setAccessible(true),然后修改它即可。
示例
package org.example.a;
import java.lang.reflect.Field;
public class Demo {
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
String s = "1234";
System.out.println("改变前:s=" + s);
Field f = s.getClass().getDeclaredField("value");
f.setAccessible(true);
f.set(s, new char[]{'a', 'b', 'c'});
System.out.println("改变后:s=" + s);
}
}
执行结果
改变前:s=1234 改变后:s=abcStringBuffer原理
其他网址
StringBuffer详解_大数据_Tut-CSDN博客
源码分析
可修改原理例程
package org.example.a;
public class Demo{
public static void main(String[] args) {
StringBuffer stringBuffer = new StringBuffer("aa");
stringBuffer.append("bbb");
System.out.println(stringBuffer);
}
}
执行结果
aabbb
源码剖析
此源码分析虽然只分析了构造函数,实际上也包含了append方法。
StringBuffer stringBuffer = new StringBuffer("aa");
//传进来参数名为str
super(str.length() + 16); //StringBuffer.java
AbstractStringBuilder(str.length() + 16) //AbstractStringBuilder.java
//value是全局变量。(一个数组)
value = new char[capacity]; //AbstractStringBuilder.java
append(str) //StringBuffer.java
toStringCache = null;
super.append(str); //调用到AbstractStringBuilder.java里
if (str == null)
return appendNull();
int len = str.length();
//确定容量是否充足,不充足则扩容。count是全局变量
ensureCapacityInternal(count + len);
//将
str.getChars(0, len, value, count); //String.java
//参数名依次为:srcBegin,srcEnd,dst[],dstBegin
//本处value为String.java的全局变量(一个数组)。(String的值)
System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
count += len;
return this;
Java--语法--final/匿名内部类/接口与抽象类的区别--final为什么不可变/匿名内部类用法_IT利刃出鞘的博客-CSDN博客



