第46節:Java當中的常量池

標題圖
Java當中的常量池
在Java虛擬機器jvm中,記憶體分佈為:虛擬機器堆,程式計數器,本地方法棧,虛擬機器棧,方法區。

JVM記憶體模型.png
程式計數器是jvm執行程式的流水線,是用來存放一些指令的,本地方法棧是jvm作業系統方法所使用的棧,而虛擬機器棧是用來執行程式程式碼的棧,在方法區中有類變數,類資訊,方法資訊,常量池(符號的引用,以表的形式存在的),堆是虛擬機器執行程式程式碼的所用的堆。
常量?是一旦給定了值就無法改變的量,用final修飾的成員變數為常量。
常量池是以表的形式存在(表是用來儲存字串值的,不儲存符號引用),實際可以分兩種,一種為靜態常量池,另一種為執行時常量池,共有11中常量表:
常量表
常量表型別 | 標誌值 | 描述 |
---|---|---|
CONSTANT_Utf8 | 1 | UTF-8編碼的Unicode字串 |
CONSTANT_Integer | 3 | int型別的字面值 |
CONSTANT_Float | 4 | float型別的字面值 |
CONSTANT_Long | 5 | long型別的字面值 |
CONSTANT_Double | 6 | double型別的字面值 |
CONSTANT_Class | 7 | 對一個類或者是介面的符號引用 |
CONSTANT_String | 8 | String型別的字面值的引用 |
CONSTANT_Fieldref | 9 | 對一個欄位的符號 |
CONSTANT_Methodref | 10 | 對一個類中方法的符號應用 |
CONSTANT_InterfaceMethodref | 11 | 對一個介面中方法的符號引用 |
CONSTANT_NameAndType | 12 | 對一個欄位或方法的部分符號引用 |
常量池
Integer integer1 = 127; Integer integer2 = 127; System.out.println(integer1 == integer2); // true Integer integer1 = 128; Integer integer2 = 128; System.out.println(integer1 == integer2); // false
在Java中符號“==”是用來比較地址,符號“equals”預設是與符號“==”一樣,都是用來比較地址的。
String string1 = "dashu"; String string2 = "dashu"; System.out.println(string1==string2); // true
String string1 = "dashu"; String string3 = new String("dashu"); System.out.println(string1 == string3); // false
在new String("dashu");,如果這個“dashu”字面值已經出現在常量池中,那麼就只出建立一個物件,如果沒有就建立兩個物件。
如果改為 string1 == string3.intern()
結果為true,因為返回的是常量池裡面字面值的地址。
棧:執行緒棧和本地方法棧
// 原始碼 public class Object{ private static native void registerNatives(); static{ registerNatives(); } } // 原始碼 public boolean equals(Object obj){ return (this == obj); } // 原始碼 public String toString(){ return getClass().getName() + "@" + Integer.toHexString(hasCode()); } // 原始碼 protected native Object clone() throws CloneNotSupportedException;
有native修飾符修飾的是通過JNI來呼叫c語言或是c++執行的。
所有的類都是Object的子類。
萬物皆物件 // 原始碼註解 Class {@code Object} is the root of theclass hierarchy. Every class has {@code Object} as a superclass. All objects, including arrays, implements the methods of this class. @ see java.lang Class @ since JDK1.0
常量池:Class檔案中儲存所有常量,在Java中說過常量池可以分兩種形態,靜態常量池和執行時常量池。
靜態常量池就是class檔案中的常量池有字串字面量,類資訊,方法的資訊等,佔用了class檔案較大部分的空間,在常量池中主要存放的是字面量和符號引用量。
執行時常量池是java虛擬機器在完成類載入後的操作,將class檔案中的常量池載入到記憶體中,並保證在方法區,我們口中的常量池是在方法區中執行的常量池,執行時常量池具有動態性,在執行期間也能產生新的常量放入池中,就是上方寫過的程式碼。
如果改為`string1 == string3.intern()`結果為true,因為返回的是常量池裡面字面值的地址。
String類的intern()方法。
往後餘生,唯獨有你
簡書作者:達叔小生
90後帥氣小夥,良好的開發習慣;獨立思考的能力;主動並且善於溝通
簡書部落格: ofollow,noindex">https://www.jianshu.com/u/c785ece603d1
結語
- 下面我將繼續對 其他知識 深入講解 ,有興趣可以繼續關注
- 小禮物走一走 or 點贊