1. java中的hashCode 是什麼?
hashCode()方法提供了對象的hashCode值,它與equals()一樣在Object類中提供,不過它是一個native方法,它的返回值默認與System.identityHashCode(object)一致,通常情況下,這個值是對象頭部的一部分二進制位組成的數字,這個數字具有一定的標識對象的意義存在,但絕對不等價於地址。
在JDK7中,Hash相關的集合類對使用String作爲Key的情況,不再使用hashCode方式,而是有了一個hash31屬性,其餘類型保持不變。
對比兩個對象的時候,即使他們的hashCode值相同,也不能說明這兩個對象時一樣的。
2. 編譯時優化和intern方法
class Test
{
public static void main(String []args)
{
String a = "a";
final String c = "a";
String b = a +"b";
String d = c +"b";
String e = getA() + "b";
String compare = "ab";
System.out.println(b == compare);//false
System.out.println(d == compare);//true
System.out.println(e == compare);//false
}
public static String getA(){
return "a";
}
}
intern方法
public static void test(){
String a = "a";
String b = a + "b";
String c = "ab";
String d = new String(b);
System.out.println(b == c);//F
System.out.println(c == d);//F
System.out.println(c == d.intern());//T
System.out.println(d.intern() == b.intern());//T
}
在HotSpotVM7及以前的版本中都是有Perm Gen(永久代)這個版塊的,在前面例子中所談到的String引用所指向的對象,他們存儲的空間正式這個版塊中的一個“常量池”區域,它對於同一個值的字符串保證全局唯一,當調用intern()方法時,JVM會在這個常量池中通過equals()方法查找是否存在等值的String,如果存在則直接返回常量池中這個String對象的地址;若沒有找到,則會創建等值的字符串(即等值的char[]數組字符創,但是char[]是新開闢的一份拷貝空間),然後再返回這個心創建空間的地址,只要是同樣的字符創,當調用intern方法時,都會得到常量池中對應String的引用,所以兩個字符串通過intern操作後用等號是可以匹配的,但是其俠侶並不高,輸在了對比地址之前要先找到地址上。
3. String的“+” 操作
字符串在進行“+”連接時,實際上底部是進行的StringBuild.append()操作。
創建一個StringBuilder對象時,這個對象內部會分配16個長度的char數組,當發生append操作時,如果空間夠用,就繼續向後添加元素;若空間不夠,則會嘗試擴展空間。擴展空間的規則是:使用當前StringBuilder的count值 + 傳入字符串的長度 作爲新的char[]數組的參考值,這個參考值將會與StringBuilder的char[]數組中長度的2倍來取最大值,也就是說最少會擴展爲原來的2倍。
其中count值並不是char[]數組的總長度,而是當前StringBuilder中有效元素的個數,或者是通過StringBuilder.length()方法得到的值,char[]數組總長度可以通過capacity()方法獲取到。
首先確認一定,並不是String的“+”操作本身慢,而是大循環中大量的內存使得它的內存開銷變大了,導致了系統頻繁GC(在很多時候程序滿都是因爲GC多造成的),而且更多的是FULL GC ,效率纔會下降。
如果是 String str = a + b + c +d + e;只會申請一個StringBuilder進行多次append()操作,因爲這是一行代碼,或者是一條語句;
Buffer中的一些方法
limit() 返回容量限制,區間大小爲[0-capacity]
flip() 將limit設置爲當前position的位置,將position設置爲0,將mark設置爲-1,這個動作的目的通常是爲了讀取Buffer中[0-position]中的所有數據
clear()用於清空緩衝區,僅將position設置0,limit設置爲與capacity同樣的大小,mark設置爲-1,數據還在,可以繼續從這裏面讀取數據,目的是爲了從新寫入數據。
4. 其他
當Integer 與 int 類型進行比較時,會將Integer轉化爲int類型來比較(也就是通過調用intValue()方法返回數字)Integer做比較的時候,Integer會自動拆箱,就是比較它的數字值。
Switch case 爲選擇語句,匹配時不會用equals(),而是直接使用“==” 而在switch case 語句中,語法層面case 部分是不能寫Integer對象的,只能是普通數字,在JDK7 中支持對String對象的switch case操作,在編譯後的字節碼文件中依然是if else語句,並且是通過equals比較的。
在反射當中,對Integer屬性不能使用field.setInt()和fiels.getInt()操作。