String面试题解析

Posted 野生java研究僧

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了String面试题解析相关的知识,希望对你有一定的参考价值。


关于String我们几乎是只要一写代码就会用到,而且关于一些面试题也会问到,我这里就列举了String 类型的变量在各种情况的一个比较,以及他们的在内存中的一个位置,因为最近也刚刚好在看jvm相关的东西,等看完也会写文章做总结。

1.new String()

new String("") 如果常量池中没有这个tom字符串对象,那就在堆中新建一个tom字符串对象,同时在常量池中也创建一个值一样的对象。


        String a="tom"; // tom是在常量池中
        // b在堆中 两个对象的完全不相同所以为false
        String b = new String("tom");
        System.out.print("1:");
        System.out.print(a==b); //false
        System.out.println();

 		/*
 		String a = new String("a");
        String b = a.intern();
        String c ="a";
	    System.out.println(c==b);
 		*/

2.通过字面量赋值创建字符串

通过字面量赋值创建字符串(如:String str=”jack”)时,会先在常量池中查找是否存在相同的字符串,若存在,则将栈中的引用直接指向该字符串;若不存在,则在常量池中生成一个字符串,再将栈中的引用指向该字符串。向常量池成一个jack到常量池。

        String d1="jack";
        // 常量池中有了,直接将d2指向常量池中的d1
        String d2="jack";
        System.out.print("2:");
        System.out.print(d1==d2); // true
        System.out.println();

3.intern()方法

调用intern() 方法时,intern方法会先去查询常量池中是否有已经存在,如果存在,则返回常量池中的引用

    //3.1 调用intern() 方法时,intern方法会先去查询常量池中是否有已经存在,如果存在,则返回常量池中的引用
        String e1 = new String("java");
        String e2 = new String("java"); // e1和e2肯定是不相同的,因为都是在堆中新建的对象
        String e3 = e1.intern(); // e3是常量池中的那个字符串
        System.out.print("3.1:");
        System.out.print(e2==e3);
        System.out.println();

4.常量字符串和变量使用+号拼接操作

常量字符串和变量使用“+”拼接时或者变量与变量拼接时会调用stringBuilder.append()在堆上创建新的对象,而不会同时在常量池里新建对象

        String f0="user";
        String f1 =f0+"Name";
        String f2="userName"; //f2首先会看常量池有没有
        System.out.print("4:");
        System.out.print(f1==f2);
        System.out.println();

5.常量字符串与常量字符串+拼接操作

常量字符串与常量字符串的“+”操作,编译阶段直接会合成为一个字符串。如String str=”Hello”+”World”,在编译阶段会直接合并成语句String str=”HelloWorld”,然后会先去常量池中查找是否存在”HelloWorld”, 如果找到直接引用,找不到创建一个新的然后放一份到字符串常量池。并不会在堆中创建新的字符串对象

6.完整代码案例

public static void main(String[] args) 
        // 1. new String("tom") 如果常量池中没有这个a字符串对象,那就在堆中新建一个tom字符串对象,同时在常量池中也创建一个值一样的对象
        String a="tom"; // tom是在常量池中
        // b在堆中 两个对象的完全不相同所以为false
        String b = new String("tom");
        System.out.print("1:");
        System.out.print(a==b);
        System.out.println();


        // 2.通过字面量赋值创建字符串(如:String str=”jack”)时,会先在常量池中查找是否存在相同的字符串,
        // 若存在,则将栈中的引用直接指向该字符串;若不存在,则在常量池中生成一个字符串,再将栈中的引用指向该字符串。
        // 向常量池成一个jack到常量池
        String d1="jack";
        // 常量池中有了,直接将d2指向常量池中的d1
        String d2="jack";
        System.out.print("2:");
        System.out.print(d1==d2); // true
        System.out.println();


        //3.1 调用intern() 方法时,intern方法会先去查询常量池中是否有已经存在,如果存在,则返回常量池中的引用
        String e1 = new String("java");
        String e2 = new String("java"); // e1和e2肯定是不相同的,因为都是在堆中新建的对象
        String e3 = e1.intern(); // e3是常量池中的那个字符串
        System.out.print("3.1:");
        System.out.print(e2==e3);
        System.out.println();

        // 3.2
        String e4 = new String("Good") + new String("Bye");
        String e5 = "GoodBye";
        String e6 = e5.intern();
        System.out.print("3.2:");
        System.out.print(e4==e6);
        System.out.print("\\t");
        System.out.print(e5==e6);
        System.out.println();


        // 4.常量字符串和变量使用“+”拼接时或者变量与变量拼接时会调用stringBuilder.append()在堆上创建新的对象,而不会同时在常量池里新建对象
        String f0="user";
        String f1 =f0+"Name";
        String f2="userName"; //f2首先会看常量池有没有
        System.out.print("4:");
        System.out.print(f1==f2);
        System.out.println();


        // 5.1常量字符串的“+”操作,编译阶段直接会合成为一个字符串。如String str=”Hello”+”World”,
        // 在编译阶段会直接合并成语句String str=”HelloWorld”,然后会去常量池中查找是否存在”HelloWorld”,
        // 如果找到直接引用,找不到创建一个新的然后放一份到字符串常量池。
        String g1="Hello"+"World"; // 放入一份“HelloWorld”到常量池
        String g2="HelloWorld";  // 直接指向常量池中的那份“HelloWorld”
        System.out.print("5.1:");
        System.out.print(g1==g2);
        System.out.println();

        // 5.2
        final String g3="See";
        final String g4="You";
        String g5=g3+g4;
        String g6="SeeYou";
        System.out.print("5.2:");
        System.out.print(g1==g2);
        System.out.println();

    

参考:《深入java虚拟机3》

以上是关于String面试题解析的主要内容,如果未能解决你的问题,请参考以下文章

2020年1-6月份Java面试题总结,20多类1100道面试题含答案解析

Golang面试题解析

Java面试题|String属于基础的数据类型吗?

java面试题09

C经典面试题之深入解析sprintfstrcpy和memcpy的使用与区别

Redis高频面试题整理(含答案解析)