對象包裝器
將基本數據類型包裝在對象中,通過定義屬性和方法來豐富數據類型的操作,這樣的類稱作對象包裝器類.java中的對象包裝器類有 Byte,Short,Integer,Long,Float,Double,Boolean,Character,Void.
特點:
- 對象包裝器類是不可變的,因爲它包裝的基本類型值是final修飾的
- 對象包裝器類是final修飾的,所以不能擴展它
java自動拆箱和自動裝箱是jdk1.5之後引進的,是一種編譯現象,編譯器在生成字節碼的時候,會插入必要的方法調用.
自動裝箱:當一個int類型的值賦值給Interget變量時,int類型會被包裝成一個Integer類型的對象
自動拆箱:當一個Integer類型的對象賦值給int時,Integer類的對象會自動的拆箱變爲一個int值;
自動裝箱和拆箱在算術表達式中比較頻繁,如下
通過反編譯工具可以看出
自動裝箱時調用的是 public static Integer valueOf(int i)方法
自動拆箱時調用的是 public static intValue()方法
對象包裝器類的相關類圖
Number源碼分析
抽象類Number是BigDecimal,BigInteger,Byte,Double,Float,Integer,Long和Short類的超類.Number的子類必須提供將表示的數值轉換爲byte,double,float,int,long和short的方法
public abstract class Number implements Serializable{
private static final long serialVersionUID = -8742448824652078965L;
/**
* 以byte形式返回指定的數值,涉及到舍入或取整
* @return 轉換爲byte類型後該對象表示的值
*/
public byte byteValue() {
return (byte)intValue();
}
/**
* 以short形式返回指定的數值,涉及到舍入或取整
* @return 轉換爲short類型後該對象表示的值
*/
public short shortValue(){
return (short)intValue();
}
/**
* 以int形式返回指定的數值,涉及到舍入或取整
* @return 轉換爲int類型後該對象表示的值
*/
public abstract int intValue();
/**
* 以long形式返回指定的數值,涉及到舍入或取整
* @return 轉換爲long類型後該對象表示的值
*/
public abstract long longValue();
/**
* 以double形式返回指定的數值,涉及到舍入
* @return 轉換爲long類型後該對象表示的值
*/
public abstract double doubleValue();
/**
* 以float形式返回指定的數值,涉及到舍入
* @return 轉換爲float類型後該對象表示的值
*/
public abstract float floatValue();
}
Comparable接口
此接口強行對實現它的每個類的對象進行整體排序,這種排序被稱爲類的自然排序
類的compareTo方法被稱爲它的自然比較方法
實現此接口的對象列表(和數組)可以通過Collections.sort(和Arrays.sort)進行自動排序,實現此接口的對象可以用作
有序映射中的鍵或有序集合中的元素,無需指定比較器
public interface Comparable<T>{
public int compareTo(T o);
}
Serializable接口(是個標記接口)
類通過實現java.io.Serializable接口來啓用其序列化功能,未實現此接口對的類將無法使其任何狀態序列化或反序列化.
可序列化的所有子類型本身都是可序列化的.
要允許不可序列化類的子類型序列化,可以假定該子類型負責保存和恢復超類型的public,protected和(如果可訪問)包字
段的狀態的責任.子類型可以承擔此責任,只有當它擴展的類具有可訪問的無參構造器來初始化類的狀態時,纔可以假定
子類型有此職責,如果不是這種情況,則聲明一個類可序列化類時錯誤的
如果可序列化類未顯示聲明serialVersionID,則序列化運行時將基於該類的各個方面計算該類的默認serialVersionUID值
public interface Serializable {
}
Integer,Short,Byte,Character,Long的緩存
Integer,Short,Byte,Character,Long等使用靜態內部類提供了緩存機制用於將常用的數據[-128,127]對象存儲.提高內存的利用率和效率,因此當自動裝箱時,相同的int值對應的包裝對象指向同一個引用,只有當int值不在緩存中時,纔會創建新的對象.其中Integer的包裝類型可以通過修改JVM參數來指定緩存的上限.
public class Integer extends Number{
private final int value;
private static class IntegerCache{
static final low = -128; //緩存的默認下限
static final high; //緩存的默認上限
static final Integer[] cache; //保存緩存的Integer對象
static{
int h = 127; //設置默認的緩存上限
// 獲取jvm關於java.lang.Integer.IntegerCache.high的設置
String integerCacheHighPropValue = sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if(integerCacheHighPropValue != null){
try{
// 將integerCacheHighPropValue解析爲int,如果不能解析,則拋出 NumberFormatException 異常,默認不對這個異常做處理
int i = parseInt(integerCacheHighPropValue);
/* 查看設置值是否大於默認值,如果設置值未大於默認值,則繼續使用默認上限127,即設置IntegerCache.high的值無效,此時緩存數組
的大小爲 127 - (IntegerCahe.low)+1=256(加1是因爲1~127,-1~127中沒有包括0)
*/
i = Math.max(i,127);
/**
查看此時的上限值是否大於Integer.MAX_VALUE-(-low)-1(
爲什麼是這個值呢?
因爲數組的大小最大隻能取到MAX_VALUE,默認緩存下限是low=-128,所以要減去
-128~-1和0所佔的數組空間.
)
如果大於,則設置緩存的上限爲Integer.MAX_VALUE,即設置參數不起作用
*/
h = Math.min(i,Integer.MAX_VALUE-(-low)-1);
}catch(NumberFormatException nfe){
}
}
high = h; //獲得最終的緩存上限
// 創建緩存數組並循環賦值
cache = new Integer[high-low+1];
int j = low;
for(int k = 0;k<cache.length;k++){
cache[k] = new Integer(j++);
}
assert Integer.high >= 127;
}
}
public static Integer valueOf(int i){
if(i >= IntegerCache.low && i<= IntegerCache.high)
return IntegerCache.cache[i+(-IntegerCache.low)];
return new Integer(i);
}
public static intValue(){
return value;
}
}