8.5字符串池String_Pool 9.4.4String.intern()方法

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;
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容