java.lang.String 源码
package java.lang;
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
//字符串对象是不可变(immutable)的,一旦构造好之后,就无法再改变其状态
private final char value[];
//字符串的hash码
private int hash; // Default to 0
// 其他代码..........................................
//本地方法
public native String intern();
}
为了节约内存,Java虚拟机内部维护了一个字符串池。提供了intern()实例方法,可以把自己放入字符串池。↑常量池必须是本地方法,因为这是一个实现jvm的语言的语言的string 为key java的String 为value的 字符串转换缓存
很多构造方法 其中一个是 根据char[]来构造
public String(char[] value) {
this.value = Arrays.copyOf(value, value.length);
}
String 和其他对象不同在于,有一个StringPool,里面是一个map<本地语言字符串,java的String对象>,存取都通过它 相当于classLoad
java的main入口也有String[] 所以 java/lang/String
,[Ljava/lang/String
,[C
一开始就被class加载了
String对象内部由char[]构成
{
Class: `java/lang/String`
slots: char[]
}
9.4.4 String.intern()本地方法
如果字符串还没有入池,把它放入并返回该字符串,本来就有,返回老的那个
package jvmgo.book.ch09;
public class StringTest {
public static void main(String[] args) {
String s1 = "abc1";
String s2 = "abc1";
System.out.println(s1 == s2); // true
String s3 = "abc" + x;
s3 = s3.intern();
System.out.println(s1 == s3); // true
}
}
NativeMethod intern=frame -> {
OObject thisStringObject = frame.getLocalVars().getRef(0);
OObject interned= StringPool.internString(thisStringObject);
frame.getOperandStack().push(interned);
};
StringPool.internString(thisStringObject):
public static Object internString(Object aStringObject) {
String string = getString(aStringObject);
Object object = internedStrings.get(string);
if(object !=null){
return object ;
}
internedStrings.put(string,aStringObject);
return aStringObject;
}