共计 2695 个字符,预计需要花费 7 分钟才能阅读完成。
最近在看一些 String 的面试题,而后就想着把它整顿起来,之后如果还有看到其余的也会持续增加进来
常见问题
1.String 中,== 和 equals()的区别
答:equals 实质上是 ==,然而 String 重写了 equals 办法,在 String 中,== 比拟的是两个对象的援用地址是否相等,而 equals 比拟的是两个字符串对象的字面量是否相等。
2. 两个对象的 hashCode 雷同,equals 肯定雷同吗?
答:不是,两个对象的 hash 雷同,equals 不肯定雷同,然而 equals 雷同,hashCode 肯定雷同
3. 创立 String 对象有几种形式
String a = "";
String b = new String();
String c = String.class.newInstance();
clone 的形式
反序列化的形式
4. 在 Java 中,创建对象有几种形式
1)new 一个 对象
2)通过构造方法
3)利用反射创立一个对象 --String.class.newInstance()
4)利用 Object 的 clone 办法
5)反序列化形式
5. 以下代码创立出几个对象?—4 个
String a = "abc";
String b = new String("abc");
String c = "abc";
String d = new String("xyz");
6. 以下代码创立出几个对象?
答:依据不同的编译器有不同的状况
- 有的 java 编译器是创立 3 个对象,”abc” 一个,”xyz” 一个,两者相加当前又造成一个对象 ”abcxyz”
- 官网的编译器,只会创立出 1 个,在编译阶段它将 ”abc” 和 ”xyz” 拼接在一起造成一个对象 ”abcxyz”,对象 a 存着该 ”abcxyz” 的援用地址
String a = "abc" + "xyz"
7. 以下代码会创立几个对象?
答:0 个,只会有一个新的索引 a,空串在 Java 虚拟机启动的时候默认生成的
String a = "";
8. 以下代码会创立几个对象?
答:4 个,首先 ”abc” 对象在常量池里被创立,而后在堆内存里创立了对象 b,之后 ”xyz” 对象在常量池被创立,而后用 += 进行拼接的时候,b 被结构成 StringBuilder 对象,调用 append 拼接了 ”xyz”,之后原本应该是要调用 toString()办法转换成 String 对象,然而 += 把这一步给省略了
String b = new String("abc");
b += "xyz";
9. 以下的第三行代码创立出几个对象(第一和第二行不算入)
String var1 = "abc";
String var2 = new String("abc");
String str = var1 + var2;
答:两个对象,一个是 String 对象,另一个是 StringBuilder 对象,当咱们没有应用 str 变量时,底层会创立一个 StringBuilder 对象,调用 append 办法把 var1 和 var2 拼接起来,最初调用 toString()办法返回。
而当咱们应用 str 变量时,产生出一个 String 对象,编译器会做一个优化。底层是通过 var1+var2 办法拼接字符串,比方如下.class 代码:
应用 str:public static void main(String[] args) {
String var1 = "abc";
String var2 = new String("abc");
String str = var1 + var2;
System.out.println(str);
}
不应用 str:public static void main(String[] args) {
String var1 = "abc";
String var2 = new String("abc");
(new StringBuilder()).append(var1).append(var2).toString();}
10.new String(“abc”)底层的创立过程?
答:首先,先在常量池外面创立一个 ”abc” 字符串对象,这个对象指向了一个 char 数组[‘a’,’b’,’c’],而后在堆内存里开拓一块空间创立了 String 对象,这个字符串对象也指向了这个 char 数组
11.String 字符串的 hash 值什么时候被赋值
答: 默认 hash 值为 0,当调用带 String 参数的构造方法时会被初始化为传入的那个字符串参数的 hash,还有就是当调用字符串的 hashCode 办法时 hash 值会被计算出来
12. 以下代码打印进去的后果是什么
答:是 abc,应用带 char 数组参数的构造方法,底层是把 char 数组的内容复制一份给了字符串,所以 chars 数组和 str 底层的 value 数组不是同一个数组,即便扭转了 chars 数组的内容,str 还是不变。
char[] chars = {'a','b','c'};
String str = new String(chars);
chars[0] = 'x';
System.out.println(str);
13. 以下三种创立 String 对象的形式有什么区别吗?
String str1 = new String();
String str2 = new String("");
String str3 = "";
答:str1 和 str2 都是在堆内存里创立了一个对象,并指向了 ”” 字符串的援用地址,然而 str2 在结构的时候并把 ”” 字符串的 hash 值赋给了 str2,所以相比于 str1 来说,在之后的操作中,就不必再去计算 hash 值,性能会进步。而 str3 相比于前两种,它只是在栈内存里开拓了一个空间指向了常量区里的 ”” 字符串对象
14. 以下代码中,str2 和 str3 哪种创立形式更好?
String str1 = "abc";
String str2 = new String("abc");
String str3 = new String(str1);
答:str2 和 str3 两个对象都是指向常量区外面同一个 ”abc” 字符串对象的 value 数组,所以从运行层面上来看两种办法都是一样的。
但在编译的时候,如果间接用字符串常量的形式结构,编译器会去遍历常量区里的所有字符串,直到找到 ”abc” 字符串,再去结构 str2。而 str3 在结构的时候,因为 str1 指向的是一个援用地址,相当于间接通知 str3 你要的字符串常量就在我保留的这个地位,这样就省去了遍历常量区的过程,速度会更快一点。
15. 为什么在循环的时候,String 用 + 号进行字符串拼接效率低?
答:因为应用 + 进行拼接的话,编译器每一次的拼接都会创立一个 StringBuilder 对象将每个 + 号前面的字符串通过 append 办法拼接起来,然而每循环一次都会产生一个 StringBuilder 对象,当循环的次数很大的时候,效率天然就升高了