有关于String
作者:互联网
1 首先明白 jvm 内存结构
1.8 之前
最主要:
堆:1 线程共享 2 属于内存空间(可以是连续的内存地址 也可以是非连续 主要由gc 进行管理 也可以不管了,主要作用就是 存放 java 对象),
栈:1 线程私有 ,随着线程的消失而消失 2 属于内存空间 (栈帧 来控制 ,调方法之前,先压一个栈帧(包含一些变量 ,), 调完方法之后 出栈,也可以使用return 强行出栈) 3 栈的设计是按照 数据结构中的 栈设计
假如我们 一个类有:多个方法
public class Test {
void functionA(String a ){
}
void functionB(String b ){
}
void functionc(String a,String b ){
functionB(b);
functionA(a);
}
}
假设只有一个主线程来跑这个Test类。
最先是入的栈:
functionc.functionA(a); 然后是 functionc.functionB(b) 然后是 functionB 然后是 functionA
出栈:
functionA 然后 functionB 然后是 functionc.functionB(b) 然后是 functionc.functionA(a)
这样 主线程就可以 按顺序 执行所有方法。
============================================
扯远了:
回到String 源码
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
private final char value[];
public String concat(String str) {
int otherLen = str.length();
if (otherLen == 0) {
return this;
}
int len = value.length;
char buf[] = Arrays.copyOf(value, len + otherLen);
str.getChars(buf, len);
return new String(buf, true);
}xia
public String substring(int beginIndex) {
if (beginIndex < 0) {
throw new StringIndexOutOfBoundsException(beginIndex);
}
int subLen = value.length - beginIndex;
if (subLen < 0) {
throw new StringIndexOutOfBoundsException(subLen);
}
return (beginIndex == 0) ? this : new String(value, beginIndex, subLen);
}
}
首先:String 本质上是, final char value[] ; 不可变数组
那么如果 要改变Sting 怎么办,
String a = "hell"
String b = "world"
String c = a.concat(b);
String d = "helloworld";
String f = "hello"+"world";
System.out.println(d == c);
System.out.println(d == a+b);
System.out.println(d == f);
jvm 做了什么,
char buf[] = Arrays.copyOf(value, len + otherLen); 向String 常量池 申请一个 新长度 字符数组 ,将旧的字符串 一个一个拼接到新的 char buf[]
然后 new String(buf, true);返回。
也就是 new 了一个 c 对象,c的成员还是 从 a b 的 char value[] 复制过来。也就是jvm 常量池中 只有三个变量 : hell world helloworld
这么做的好处:1 目的是为了避免字符串的重复创建。2 不用考虑 Stirng 对象改变所带来的麻烦 ,如果这个string是可以改变的,通过一个引用改变一个string将导致另一引用指向错误的值。
标签:beginIndex,String,value,functionA,关于,new,buf 来源: https://www.cnblogs.com/publicmain/p/16251827.html