常见易错的Java String面试题
下面说明一些String相关的面试题,加深理解,助你面试成功一臂之力。
1、下面这段代码的输出结果是什么?
String a = "hello1024";
String b = "hello" + 1024;
System.out.println((a == b));
输出结果为:true。因为:“hello”+1024在编译期间就已经被优化成"hello1024",因此在运行期间,变量a和变量b指向的是同一个对象。
我们反编译下代码可以看到,“hello”+1024在编译期间就已经被优化成"hello1024"。
2、下面这段代码的输出结果是什么?
String a = "hello1024";
String b = "hello";
String c = b + 1024;
System.out.println((a == c));
输出结果为:false。由于有符号引用的存在,所以 String c = b + 1024;不会在编译期间被优化,不会把b+2当做字面常量来处理的,因此这种方式生成的对象事实上是保存在堆上的。因此a和c指向的并不是同一个对象。
反编译代码我们看到,c = b + 1024,是先new了一个StringBuilder对象,再append上1024,最后toString得到字符串,引用赋值给c。
3、下面这段代码的输出结果是什么?
String a = "hello1024";
final String b = "hello";
String c = b + 1024;
System.out.println(a == c);
输出结果为:true。对final变量的访问在编译期间都会直接被替代为真实的值。那么String c = b + 1024;在编译期间就会被优化成:String c = “hello” + 1024;
我们反编译下代码可以看到,“hello”+1024在编译期间就已经被优化成"hello1024"。
4、下面这段代码的输出结果是什么?
public static String getHello() {
return "hello";
}
public static void main(String[] args) {
String a = "hello1024";
final String b = getHello();
String c = b + 1024;
System.out.println(a == c);
}
输出结果为:false。这里面虽然将b用final修饰了,但是由于其赋值是通过方法调用返回的,那么它的值只能在运行期间确定,因此a和c指向的不是同一个对象。
反编译代码我们可以看到,c = b + 1024,是先new了一个StringBuilder对象,再append上1024,最后toString得到字符串,引用赋值给c。
5、下面这段代码的输出结果是什么?
String a = "hello";
String b = new String("hello");
String c = new String("hello");
String d = b.intern();
System.out.println(a==b);
System.out.println(b==c);
System.out.println(b==d);
System.out.println(a==d);
输出结果为:
false
false
false
true
Java源码中我们可以看到,在String类中,intern方法是一个本地方法,intern方法会在运行时常量池中查找是否存在内容相同的字符串,如果存在则返回指向该字符串的引用,如果不存在,则会将该字符串入池,并返回一个指向该字符串的引用。因此,a和d指向的是同一个对象。
6、String str = new String(“helloworld”)创建了多少个对象?
答案:2个对象。
反编译下我们看到:
很显然,new只调用了一次,也就是说只创建了一个String对象。
这道题目让人混淆的地方就是这里,这段代码在运行期间确实只创建了一个对象,即在堆上创建了对象。而为什么大家都在说是2个对象呢,这里面要澄清一个概念 该段代码执行过程和类的加载过程是有区别的。在类加载的过程中,确实在运行时常量池中创建了一个"helloworld"对象,而在代码执行过程中确实只创建了一个String对象。
面试时要向面试官说清楚创建了几个对象,分别是什么时候什么地方创建的。
7、下面这段代码<1>和<2>的区别是什么?
package com.test.string;
public class Test {
public static void main(String[] args) {
String str = "I";
//str += "love"+"java"; //<1>
str = str+"love"+"java"; //<2>
}
}
<1>的效率比<2>的效率要高。
<1>中的"love"+“java"在编译期间会被优化成"lovejava”,而<2>中的不会被优化。下面是两种方式的字节码:
<1>的字节码:
<2>的字节码:
可以看出,在<1>中只进行了一次append操作,而在<2>中进行了两次append操作。
欢迎小伙伴们关注转发点赞,谢谢~~
浏览更多文章可关注微信公众号:diggkr