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道面试题含答案解析