「優先重用對象而非每次創建新對象。不可變對象天然可重用;可變對象若確不會被修改,也可重用。」
// 反例:每次執行創建新對象
String s = new String("啪啪啪"); // 堆中新對象 + 常量池 "啪啪啪" = 2 個對象
// 正例:複用常量池實例
String s = "啪啪啪"; // 僅 1 個對象,所有相同字面量共享
循環/高頻調用中差異巨大。JDK 1.7+ 常量池移至堆,GC 可回收無引用常量。
// 構造器:每次 new
Integer a1 = new Integer("1");
Integer a2 = new Integer("1");
System.out.println(a1 == a2); // false
// valueOf:緩存 -128~127,複用實例
Integer a3 = Integer.valueOf("1");
Integer a4 = Integer.valueOf("1");
System.out.println(a3 == a4); // true
Boolean.valueOf、Long.valueOf 同理。自定義不可變類亦可提供靜態工廠。
反例:每次調用創建新連接
public static Connection getConnection() { // 每次 new
Class.forName("com.mysql.jdbc.Driver");
return DriverManager.getConnection(URL, USER, PWD);
}
正例:靜態初始化/單例模式
private static Connection conn;
static {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection(URL, USER, PWD);
}
public static Connection getConnection() { return conn; }
提升性能、簡化邏輯。生產環境建議用成熟連接池(HikariCP/Druid)。
Map<String, Object> map = new HashMap<>();
Set<String> set1 = map.keySet();
map.put("D", "D");
Set<String> set2 = map.keySet();
System.out.println(set1 == set2); // true,同一視圖實例
// 視圖隨 Map 變化自動更新,無需重複創建
// 反例:Long 包裝類,循環創建 2^31 個對象 Long sum = 0L; for (long i = 0; i < Integer.MAX_VALUE; i++) sum += i; // 正例:基本類型 long long sum = 0L; for (long i = 0; i < Integer.MAX_VALUE; i++) sum += i;
一字之差(Long vs long),性能相差數量級。**優先使用基本類型,警惕隱式裝箱**。