一.相關概念java
二.8種基本類型的包裝類和常量池緩存
Integer i1 = 40; Integer i2 = 40; System.out.println(i1==i2);//輸出TRUE
這5種包裝類默認建立了數值[-128,127]的相應類型的緩存數據,可是超出此範圍仍然會去建立新的對象。分佈式
//Integer 緩存代碼 : public static Integer valueOf(int i) { assert IntegerCache.high >= 127; if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); } Integer i1 = 400; Integer i2 = 400; System.out.println(i1==i2);//輸出false
Double i1=1.2; Double i2=1.2; System.out.println(i1==i2);//輸出false
Integer i1 = 40; Integer i2 = new Integer(40); System.out.println(i1==i2);//輸出false
Integer i1 = 40; Integer i2 = 40; Integer i3 = 0; Integer i4 = new Integer(40); Integer i5 = new Integer(40); Integer i6 = new Integer(0); System.out.println("i1=i2 " + (i1 == i2)); System.out.println("i1=i2+i3 " + (i1 == i2 + i3)); System.out.println("i1=i4 " + (i1 == i4)); System.out.println("i4=i5 " + (i4 == i5)); System.out.println("i4=i5+i6 " + (i4 == i5 + i6)); System.out.println("40=i5+i6 " + (40 == i5 + i6)); i1=i2 true i1=i2+i3 true i1=i4 false i4=i5 false i4=i5+i6 true 40=i5+i6 true
解釋:語句i4 == i5 + i6,由於+這個操做符不適用於Integer對象,首先i5和i6進行自動拆箱操做,進行數值相加,即i4 == 40。而後Integer對象沒法與數值進行直接比較,因此i4自動拆箱轉爲int值40,最終這條語句轉爲40 == 40進行數值比較。微服務
Java中的自動裝箱與拆箱源碼分析
三.String類和常量池性能
String str1 = "abcd"; String str2 = new String("abcd"); System.out.println(str1==str2);//false
這兩種不一樣的建立方法是有差異的,第一種方式是在常量池中拿對象,第二種方式是直接在堆內存空間建立一個新的對象。學習
只要使用new方法,便須要建立新的對象。優化
String str1 = "str"; String str2 = "ing"; String str3 = "str" + "ing"; String str4 = str1 + str2; System.out.println(str3 == str4);//false String str5 = "string"; System.out.println(str3 == str5);//true
java基礎:字符串的拼接視頻
public static final String A = "ab"; // 常量A public static final String B = "cd"; // 常量B public static void main(String[] args) { String s = A + B; // 將兩個常量用+鏈接對s進行初始化 String t = "abcd"; if (s == t) { System.out.println("s等於t,它們是同一個對象"); } else { System.out.println("s不等於t,它們不是同一個對象"); } } s等於t,它們是同一個對象
A和B都是常量,值是固定的,所以s的值也是固定的,它在類被編譯時就已經肯定了。也就是說:String s=A+B; 等同於:String s="ab"+"cd";對象
public static final String A; // 常量A public static final String B; // 常量B static { A = "ab"; B = "cd"; } public static void main(String[] args) { // 將兩個常量用+鏈接對s進行初始化 String s = A + B; String t = "abcd"; if (s == t) { System.out.println("s等於t,它們是同一個對象"); } else { System.out.println("s不等於t,它們不是同一個對象"); } } s不等於t,它們不是同一個對象
A和B雖然被定義爲常量,可是它們都沒有立刻被賦值。在運算出s的值以前,他們什麼時候被賦值,以及被賦予什麼樣的值,都是個變數。所以A和B在被賦值以前,性質相似於一個變量。那麼s就不能在編譯期被肯定,而只能在運行時被建立了。
public static void main(String[] args) { String s1 = new String("計算機"); String s2 = s1.intern(); String s3 = "計算機"; System.out.println("s1 == s2? " + (s1 == s2)); System.out.println("s3 == s2? " + (s3 == s2)); } s1 == s2? false s3 == s2? true
public class Test { public static void main(String[] args) { String hello = "Hello", lo = "lo"; System.out.println((hello == "Hello") + " "); System.out.println((Other.hello == hello) + " "); System.out.println((other.Other.hello == hello) + " "); System.out.println((hello == ("Hel"+"lo")) + " "); System.out.println((hello == ("Hel"+lo)) + " "); System.out.println(hello == ("Hel"+lo).intern()); } } class Other { static String hello = "Hello"; } package other; public class Other { public static String hello = "Hello"; } true true true true false true``` 在同包同類下,引用自同一String對象. 在同包不一樣類下,引用自同一String對象. 在不一樣包不一樣類下,依然引用自同一String對象. 在編譯成.class時可以識別爲同一字符串的,自動優化成常量,引用自同一String對象. 在運行時建立的字符串具備獨立的內存地址,因此不引用自同一String對象.
若是想學習Java工程化、高性能及分佈式、深刻淺出。微服務、Spring,MyBatis,Netty源碼分析的朋友能夠加個人Java高級交流:787707172,羣裏有阿里大牛直播講解技術,以及Java大型互聯網技術的視頻免費分享給你們。