一、基礎類型有byte short int long char boolean float double八種。優化
其中byte short int long char 的包裝類型是存放在常量池(用來維護該類型所用到常量的有序集合)中的,浮點類型未實現常量池。spa
常量池存放的是>=-128和<=127中的數據,當數據不在這個範圍內時,則不在常量池中維護code
Integer a=new Integer(128); Integer b=new Integer(128);
a==b?false,因爲a,b超出127限制,不存在與常量池,因此引用不一樣。對象
public static integer valueOf(int t){ final int offset=128; if(t>=-128&&t<=127){ return IntegerCache.cache[i+offset]; } return new Integer(i) }
由valueOf方法能夠看出Integer類型在-128~127範圍是取自常量池中。blog
二、String a=new String("bb");字符串
可能建立了一個對象,也可能建立了兩個對象。編譯器
在類編譯期間,會先去常量池中查找是否有「bb」的對象,若是有則在棧中複製一份;若是沒有,先在常量池中建立一份,再複製一份到堆中。以後把引用交給棧中的s。編譯
String a = "a1"; String b = "a" + 1; System.out.println((a == b)); //result = true String a = "atrue"; String b = "a" + "true"; System.out.println((a == b)); //result = true String a = "a3.4"; String b = "a" + 3.4; System.out.println((a == b)); //result = true 分析:JVM對於字符串常量的"+"號鏈接,將程序編譯期,JVM就將常量字符串的"+"鏈接優化爲鏈接後的值,拿"a" + 1來講,經編譯器優化後在class中就已是a1。在編譯期其字符串常量的值就肯定下來,故上面程序最終的結果都爲true。
String a = "ab"; String bb = "b"; String b = "a" + bb; System.out.println((a == b)); //result = false 分析:JVM對於字符串引用,因爲在字符串的"+"鏈接中,有字符串引用存在,而引用的值在程序編譯期是沒法肯定的,即"a" + bb沒法被編譯器優化,只有在程序運行期來動態分配並將鏈接後的新地址賦給b。因此上面程序的結果也就爲false。
String a = "ab"; final String bb = "b"; String b = "a" + bb; System.out.println((a == b)); //result = true 分析:和[3]中惟一不一樣的是bb字符串加了final修飾,對於final修飾的變量,它在編譯時被解析爲常量值的一個本地拷貝存儲到本身的常量池中或嵌入到它的字節碼流中。因此此時的"a" + bb和"a" + "b"效果是同樣的。故上面程序的結果爲true。
能夠看出當字符串+常量時,能夠在編譯期優化連接的值。當字符串+引用時,編譯期沒法肯定,不能被優化class