首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Java 常量池深度解析:基本型別包裝類快取、String 國際化與 Intern 機制

     編輯:Java 綜合教學

Java 常量池深度解析:基本型別包裝類快取、String 國際化與 Intern 機制

常量池是 JVM 為提升效能、減少記憶體佔用而提供的「物件複用機制」。本文系統梳理 8 大基本型別包裝類快取範圍、String 常量池演進(JDK 7 移至堆)、intern() 手動入池與實戰避坑。

一、基本型別包裝類快取(-128 ~ 127)

Integer i1 = 100;  // 自動裝箱 → Integer.valueOf(100)
Integer i2 = 100;
System.out.println(i1 == i2); // true(快取命中)

Integer i3 = 128;
Integer i4 = 128;
System.out.println(i3 == i4); // false(超出快取範圍,新建物件)

源碼鑑證

// Integer.valueOf 核心邏輯
public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high) // low=-128, high=127
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}

// IntegerCache 靜態初始化
private static class IntegerCache {
    static final int low = -128;
    static final int high = 127;
    static final Integer cache[] = new Integer[high - low + 1];
    static { for (int i = low; i <= high; i++) cache[i - low] = new Integer(i); }
}

八大包裝類快取表

包裝類快取範圍備註
BooleanTRUE/FALSE 兩個單例全範圍快取
Byte-128 ~ 127全範圍(byte 只有 256 個值)
Short-128 ~ 127
Character0 ~ 127 (U+0000 ~ U+007F)ASCII 範圍
Integer-128 ~ 127可通過 -XX:AutoBoxCacheMax= 擴大上限
Long-128 ~ 127
Float無不快取
Double無不快取

二、String 常量池

入池方式

  1. 字面值:String s = "abc"; 編譯期確定,自動入池。
  2. String.intern():運行期手動將堆上 String 物件引用加入池中(若已存在則返回池中引用)。

JDK 7 關鍵變更

  • JDK 6: 常量池位於 永久代,大小固定,易 OOM。
  • JDK 7+: 常量池移至 Java 堆,受 GC 管理,動態擴縮,intern() 效能大幅提升。

經典面試題

String s1 = new String("abc"); // 堆上新建 "abc" 物件,字面值 "abc" 入池
String s2 = "abc";             // 直接引用池中 "abc"
System.out.println(s1 == s2);  // false(不同物件)
System.out.println(s1.intern() == s2); // true(intern 返回池中引用)

String s3 = new String("a") + new String("b"); // 堆上新建 "ab",未入池
String s4 = "ab";                              // 字面值 "ab" 入池
System.out.println(s3.intern() == s4); // JDK 6: false;JDK 7+: true(intern 會將 "ab" 加入池,s4 已在池中)

三、實戰避坑指南

  • 不要用 == 比較字串內容,永遠用 equals()。
  • 大量動態生成字串(如解析大量 XML/JSON)慎用 intern(),會佔用堆記憶體且池無上限(JDK 7+),可能導致 OOM。
  • -XX:StringTableSize= 可調整常量池哈希桶數量(預設 60013),提升 intern() 效能。
  • 基本型別包裝類比較:equals() 比值,== 比引用(快取範圍內可能相等,不可依賴)。

理解常量池機制,能寫出更省記憶體、更少 Bug 的 Java 代碼。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved