JDK源码笔记04 String

something before start

说实话String在我心里一直挺神秘的,特别是之前学的时候接触到的常量池的概念(我这会儿琢磨着不会就是一个Map吧)

感觉jvm关于String的机制比较多,所以相比于之前的会多一个说明
稍微概览了一下,感觉很多实现都是没必要看的,主要记一下一些机制上的东西

String类说明

以下说明来自String源码

  1. 所有的字符串都是String类的实例。意思就是说字符串常量也可以调用String里的方法。
    这个规则常用的地方是字符串比较的时候 "常量".equals(str) ,这样就不用对变量是否取null进行多一次的判断

  2. String是不可变类,创建之后就不能变化。StringBuffer可以支持变化字符串

  3. Java对String对象相加,其他类转换成String提供支持 //toString

  4. 除非特殊说明,给构造函数传入null会抛出异常

  5. String以UTF-16存储,增补字符以surrogate pair的形式存储

  6. 除非特殊说明,比较(compare)字符串不考虑内存地址

  7. 字符串拼接的实现方式由java编译器决定,取决于JDK版本,可能会用StringBuffer、StringBuilder或StringConcatFactory的方法。
    注:字符串+ 运算会创建一个对象,然后使用相应方法,所以效率会相应更差一点

  8. 字符串转换的方法通常是通过toString实现

属性

@Stable //一个域的组件(component)顶多被修改一次,即第一个非空值,他的值被称为稳定值(stable value)
private final byte[] value;


private final byte coder;
//有两种取值, 后面有很多的处理是把两种取值分开的,我猜应该是为了让性能更好点,因为LATIN1包含的是大部分编程中常用的字符,而且不需要考虑增补字符的情况。
//在构造函数里对字符串的内容进行判断来进行初始化
//LATIN1
//UTF16

//这个值由JVM注入,如果false,则字符串就一直都会是以UTF16的形式被处理。一般都是true
static final boolean COMPACT_STRINGS;


/** Cache the hash code for the string */
private int hash; // Default to 0

/**
* Cache if the hash has been calculated as actually being zero, enabling
* us to avoid recalculating this.
*/
private boolean hashIsZero; // Default to false;

方法

构造方法

    String(char[] value, int off, int len, Void sig) {
        if (len == 0) {
            this.value = "".value;
            this.coder = "".coder;
            return;
        }
        if (COMPACT_STRINGS) {
        
						//如果value只包含拉丁文的字符,则返回相应byte[],否则返回null
            byte[] val = StringUTF16.compress(value, off, len);
            if (val != null) {
                this.value = val;
                this.coder = LATIN1;
                return;
            }
        }
        this.coder = UTF16;
        this.value = StringUTF16.toBytes(value, off, len);
    }

intern

这是一个底层方法,以下是他的简单说明

  1. 字符串池,初始为空,由String类进行拓展 //实际上底层是hashTable
  2. intern()被调用,如果池中已经有相同的string对象(通过equal函数对比),则直接返回,否则将这个对象添加到字符串池中,返回指向这个对象的引用
  3. 所有的字符串和字符串常量都interned
public native String intern();

text-block jdk15新特性

喜极而泣

String a = """
现在
终于
可以
不用
手动拼接换行字符串了!    
:D
""";
System.out.println(a);

//输出
现在
终于
可以
不用
手动拼接换行字符串了!
:D

首尾用三个引号框起来的
就是这么简单(响指

end

所以其实无论怎么去new,其实value的值都是会复用的
然后底层确实是Map
String类也有一堆工具方法,其实基本上都可以见名知意,就不多赘述了。