Stringtable(串池)常见的面试题详解

一、比较字符串是否相等

package cn.itcast.jvm.t1.stringtable;

// StringTable [ "a", "b" ,"ab" ]  hashtable 结构,不能扩容
public class Demo1_22 {
     
    // 常量池中的信息,都会被加载到运行时常量池中, 这时 a b ab 都是常量池中的符号,还没有变为 java 字符串对象
    // ldc #2 会把 a 符号变为 "a" 字符串对象
    // ldc #3 会把 b 符号变为 "b" 字符串对象
    // ldc #4 会把 ab 符号变为 "ab" 字符串对象

    public static void main(String[] args) {
     
        String s1 = "a"; // 懒惰的
        String s2 = "b";
        String s3 = "ab";
        String s4 = s1 + s2; // new StringBuilder().append("a").append("b").toString()  new String("ab")
        String s5 = "a" + "b";  // javac 在编译期间的优化,结果已经在编译期确定为ab

        System.out.println(s3 == s4);  //false(s3在stringtable中,s5在堆中)
        System.out.println(s3 == s5);  //true(都是在stringtable中)
    }
}

ps: s4和s5区别(s4是两个变量的相加,不能确定最终的结果,所以是只能在运行期确定,它是最后是通过stringbuffer的string方法重新new出来的,所以在堆中,而s5是两个字符串常量相加,字符串常量相加,内容不变,在编译期就确定了具体的值,如果字符串常量池中有,直接从串池中拿,前面s3已经创建了所以直接拿的s3,所有s5和s3相等)

二、常见面试题(比较地址)
(1.8环境)

/**
 * 演示字符串相关面试题
 */
public class Demo1_21 {
     
    public static void main(String[] args) {
     
        String s1 = "a";
        String s2 = "b";
        String s3 = "a" + "b"; // 两个常量的拼接编译器优化为ab入池
        String s4 = s1 + s2; // new String("ab")(两个变量的拼接,在运行时通过stringbuilder进行拼接,然后通过string返回一个新的字符串)
        String s5 = "ab";
        String s6 = s4.intern();

        System.out.println(s3 == s4); // false
        System.out.println(s3 == s5); // true
        System.out.println(s3 == s6); // true

        String x2 = new String("c") + new String("d"); // new String("cd")
        x2.intern();
        String x1 = "cd";
// 问,如果调换了【最后两行代码】的位置呢,如果是jdk1.6呢
        System.out.println(x1 == x2);  //true
    }
}

关于最后问题jdk1.6的结果详述

三、创建几个对象的练习

以下几种情况(均不考虑字符串在常量池中已存在的情况)1、String a="123";
创建了1个对象

jvm在编译阶段会判断常量池中是否有 "123" 这个常量对象如果有,a直接指向这个常量的引用,如果没有会在常量池里创建这个常量对象。

2、String a=new String("123");
创建了2个对象

同情况1,jvm编译阶段判断常量池中 "123"存在与否,进而来判断是否创建常量对象,然后运行阶段通过new关键字在java heap创建String对象。

3、String a="123"+"456";
创建了1个对象

jvm编译阶段过编译器优化后会把字符串常量直接合并成"123456",所有创建对象时最多会在常量池中创建1个对象。

4、String a="123"+new String("456");
创建了4个对象

常量池对象"123" ,"456"new String("456")创建堆对象,还有一个堆对象"123456"

创建对象转发于此链接

你可能感兴趣的:(stringtable,java,面试,java,字符串,面试)