1、引子java
在各類教科書和博客中這三者常常被引用,今天覆習到內存區域,想起常量池中就是存着字面量和符號引用,其實這三者並非只在java中才有,各個語言中都有相似的定義,因此作一下總結,以示區分。數組
2、例子緩存
先舉一個簡單的例子,就很容易看懂接下來的定義了。性能
int a; //變量 final int b = 10; //b爲常量,10爲字面量 string str = 「hello world!」; // str 爲變量,hello world!爲字面量
3、各定義以及區分spa
3.1 變量code
有些數據在程序運行中能夠變化或者被賦值,這稱爲變量。例如:對象
int a; String b;
3.2 常量blog
java中是指以final關鍵字修飾的變量(C語言中是constant關鍵字),在初始化的時候必須被賦值,而且此值和類型不能再發生改變。例如:內存
final int a; final String b;
3.3 字面量字符串
在計算機科學中,字面量(literal)是用於表達源代碼中一個固定值的表示法(natation)。
是否是仍是看不懂?我通常採用一個特殊的區分方法:等號右邊的八種基本類型的值、字符串值、聲明爲final的常量的值。例如:
final int a = 10; //a爲常量,10爲字面量 string b = 「hello world!」; // b 爲變量,hello world!爲字面量
4、Integer的緩存機制
注意,有個容易誤解的地方:關於Integer在-128到127之間的緩存問題。
這個問題不少人其實都知道——若是值在-128到127之間,Integer對象的引用地址是相等的。身邊不少朋友都說是字面量在常量池中緩存的緣由。
其實並非的,這是Integer的緩存機制:
在Integer類中,定義了一個私有的靜態類IntegerCache,這個類是用來支持Integer緩存的,它的做用是把一部分Integer類型的對象在Integer類加載的時候一塊兒建立出來並放在一個cache數組中,以便之後循環使用。一般這個範圍是-128-127,然而這個範圍的最大值是可變的,能夠經過-XX:AutoBoxCacheMax=<size>參數去修改這個值,在JVM初始化的時候,這個值被寫入sun.misc.VM class系統私有配置文件中,並加載。(由於會一次性所有建立出來,因此這個數值會影響到啓動性能)
【Byte,Short,Long 有固定範圍: -128 到 127。對於 Character, 範圍是 0 到 127。除了 Integer 能夠經過參數改變範圍外,其它的都不行。】
... cache = new Integer[(high - low) + 1]; int j = low; for(int k = 0; k < cache.length; k++) cache[k] = new Integer(j++); ...
而後在調用valueOf(int i)方法的時候(自動封裝就是調用這個方法),就會判斷 i 是否在這個範圍以內,是的話就會返回這個靜態類維護的cache數組裏對應的對象。因此說在這個範圍內值相同的對象的引用是相同的。
public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }
示例:
Integer integer1 = new Integer(121); Integer integer2 = 121; // 編譯器編譯成調用valueOf(int i) Integer integer3 = Integer.valueOf(121); System.out.println(integer1 == integer2); // false System.out.println(integer2 == integer3); // true
可見new出來的對象並不會從Integer緩存中去取。