面试题答案
一键面试字符串拼接
在字符串拼接场景中,由于 String
类的不可变性,每次拼接操作都会生成一个新的 String
对象。例如:
String str1 = "Hello";
String str2 = "World";
String result = str1 + str2;
这里 str1
和 str2
本身并不会改变,str1 + str2
操作会在堆内存中创建一个新的 String
对象来存储 "HelloWorld"
,result
指向这个新对象。如果在循环中进行大量字符串拼接,会频繁创建新对象,占用大量内存,影响性能。此时更适合使用 StringBuilder
或 StringBuffer
类,它们是可变的,不会每次操作都创建新对象。
常量池
- 常量池的概念:Java 有字符串常量池,用于存储程序中出现的字面量字符串。当代码中出现字面量字符串时,JVM 会先在常量池中查找是否已存在相同内容的字符串对象。
- 不可变性与常量池关系:因为
String
是不可变的,所以常量池中的字符串可以被多个引用共享而不会出现数据不一致问题。例如:
String s1 = "abc";
String s2 = "abc";
这里 s1
和 s2
指向常量池中的同一个 "abc"
对象,节省了内存空间。如果 String
是可变的,一个引用对字符串的修改会影响到其他引用,破坏常量池共享机制。
作为参数传递
当 String
作为方法参数传递时,由于其不可变性,不用担心方法内部会修改传入字符串的内容。例如:
public class Main {
public static void modifyString(String str) {
str = str + " modified";
}
public static void main(String[] args) {
String original = "Hello";
modifyString(original);
System.out.println(original); // 输出 "Hello",original 内容未改变
}
}
在 modifyString
方法中对 str
的操作只是创建了一个新的字符串对象,原 original
字符串并未改变,保证了数据的安全性和程序逻辑的稳定性。
哈希表应用
String
的不可变性使其非常适合作为哈希表的键。因为不可变,所以其哈希值在创建后不会改变,这满足了哈希表键的要求。如果 String
可变,一旦字符串内容改变,哈希值也会改变,就无法在哈希表中正确定位该键对应的值。例如在 HashMap
中使用 String
作为键:
HashMap<String, Integer> map = new HashMap<>();
String key = "apple";
map.put(key, 10);
// 由于 key 不可变,无论在何处使用 key,其哈希值始终不变,能准确获取到值 10