String
真正不可變有下面幾點原因:
- 儲存字串的陣列被
final
修飾且為私有的,並且String
類沒有提供/暴露修改這個字串的方法。 String
類被final
修飾導致其不能被繼承,進而避免了子類破壞String
不可變。
字串拼接用“+” 還是 StringBuilder?
bad case
String[] arr = {"he", "llo", "world"};
String s = "";
for (int i = 0; i < arr.length; i++) {
s += arr[i];
}
System.out.println(s);
String#intern 方法有什麼作用?
String.intern()
是一個 native(本地)方法,其作用是將指定的字串物件的引用儲存在字串常量池中,可以簡單分為兩種情況:
- 如果字串常量池中儲存了對應的字串物件的引用,就直接返回該引用。
- 如果字串常量池中沒有儲存了對應的字串物件的引用,那就在常量池中建立一個指向該字串物件的引用並返回。
String 型別的變數和常量做“+”運算時發生了什麼?
String str1 = "str";
String str2 = "ing";
String str3 = "str" + "ing";
String str4 = str1 + str2;
String str5 = "string";
System.out.println(str3 == str4);//false
System.out.println(str3 == str5);//true
System.out.println(str4 == str5);//false
對於編譯期可以確定值的字串,也就是常量字串 ,jvm 會將其存入字串常量池。並且,字串常量拼接得到的字串常量在編譯階段就已經被存放字串常量池,這個得益於編譯器的最佳化。
引用的值在程式編譯期是無法確定的,編譯器無法對其進行最佳化。
不過,字串使用 final
關鍵字宣告之後,可以讓編譯器當做常量來處理。
注意:不要在 finally 語句塊中使用 return!
當 try 語句和 finally 語句中都有 return 語句時,try 語句塊中的 return 語句會被忽略。這是因為 try 語句中的 return 返回值會先被暫存在一個本地變數中,當執行到 finally 語句中的 return 之後,這個本地變數的值就變為了 finally 語句中的 return 返回值。
背一下動態代理?
public class DebugInvocationHandler implements InvocationHandler {
/**
* 代理類中的真實物件
*/
private final Object target;
public DebugInvocationHandler(Object target) {
this.target = target;
}
public Object invoke(Object proxy, Method method, Object[] args) throws InvocationTargetException, IllegalAccessException {
System.out.println("before method " + method.getName());
Object result = method.invoke(target, args);
System.out.println("after method " + method.getName());
return result;
}
}
SPI 和 API 有什麼區別?
- 當介面存在於呼叫方這邊時,這就是 **SPI ** 。由介面呼叫方確定介面規則,然後由不同的廠商根據這個規則對這個介面進行實現,從而提供服務。