字符串-intern


String:intern()是一个本地方法,它的作用是如果字符串常量池中已经包含一个等于此String对象的字符串,则返回代表池中这个字符串的String对象的引用;否则,会将此String对象包含的字符串添加到常量池中,并且返回此String对象的引用。

public class InternDemo {
    public static void main(String[] args) {
        String a = new StringBuffer("chen").append("fei").toString();
        System.out.println(a);
        System.out.println(a.intern());
        System.out.println(a == a.intern());

        System.out.println("----------");

        String b = new StringBuffer("ja").append("va").toString();
        System.out.println(b);
        System.out.println(b.intern());
        System.out.println(b == b.intern());

    }
}

输出结果:

chenfei
chenfei
true
----------
java
java
false

按照代码结果,Java字符串答案为false必然是两个不同的java,那另外一个java字符串如何加载进来的?

有一个初始化的Java字符串(JDK出娘胎自带的),在加载sun.misc.Version这个类的时候进入常量池。

System代码解析 System -> initializeSystemClass() -> Version

package java.lang;

public final class System {

    /* register the natives via the static initializer.
     *
     * VM will invoke the initializeSystemClass method to complete
     * the initialization for this class separated from clinit.
     * Note that to use properties set by the VM, see the constraints
     * described in the initializeSystemClass method.
     */
    private static native void registerNatives();
    static {
        registerNatives();
    }

    //本地方法registerNatives()将会调用initializeSystemClass()
    private static void initializeSystemClass() {

        ...

        sun.misc.Version.init();

        ...
    }
    ...
}
package sun.misc;

//反编译后的代码
public class Version {
    private static final String launcher_name = "java";
    ...
}

类加载器和rt.jar - 根加载器提前部署加载rt.jar

sun.misc.Version类会在JDK类库的初始化过程中被加载并初始化,而在初始化时它需要对静态常量字段根据指定的常量值(ConstantValue〉做默认初始化,此时被sun.misc.Version.launcher静态常量字段所引用的”java”字符串字面量就被intern到HotSpot VM的字符串常量池——StringTable里了。


文章作者: Adbo
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Adbo !
评论
  目录