1.Java中的八種基本數據類型不是對象,之所以這樣設計,是因爲其使用方便,效率高於對象類型。但是集合類並不支持對基本數據類型的操作。因此就引入了包裝器類。在JDK1.5之後加入了自動拆裝箱機制。裝箱時調用valueOf方法,這是個靜態方法,返回包裝器類型,值爲形參的值。拆箱時調用xxxvalue方法,返回基本數據類型。
包裝器類型參與運算時用到符合賦值運算可能會報錯:
Short sh1=Short.valueOf((short) 1);
Short sh2=2;
//sh1+=sh2;//相當於 sh1=(Short)(sh1+sh2);
第三行會報錯。相加時先拆箱,後提升至int類型,在轉化爲Integer類型。在將Integer類型強轉爲Short類型時出錯。因爲參與運算的類型時int類型,所以將Short類型轉換爲Integer時可以通過編譯。
Integer i1=1;
Integer i2=2;
i1+=i2;
System.out.println(i1);
先拆箱,後運算,再裝箱。
包裝類的緩存:在java中,String和包裝器類型都是有final修飾的。因此,對象一經創建後就不可修改。對此,String類提供了常量池,包裝器類提供了對象的緩存,具體實現是在類中預先創建頻繁使用的包裝類對象。當需要某個包裝類對象時,如果該對象的值在緩存的值的範圍內,就返回包裝類的對象,否則就創建新的並返回。緩存的優點:
- 當頻繁使用包裝類對象時,可以直接返回緩存類中事先創建好的對象。節省創建對象的時間開銷。因爲包裝類是不可變的,因此,它的對象可以自由共享。
緩存的範圍:
- 數字類型(Byte、Short、Integer、Long)都是-128~127;
- Character類:0~127;
- Boolean類:true和false都有;
- 浮點類型(Float、Double):沒有緩存值。
Integer i1=127;//自動裝箱,調用Integer.valueOf()方法
Integer i2=127;//不能new,new會在堆上創建新對象。地址一定不一樣。這一點和字符串一樣
public class Maintest extends Super{
public static void main(String[] args) {
Integer i1=127;//自動裝箱,調用Integer.valueOf()方法
Integer i2=127;//不能new,new會在堆上創建新對象。地址一定不一樣。這一點和字符串一樣
System.out.println("i1.equals(i2):"+i1.equals(i2));
System.out.println("i1==i2:"+(i1==i2));
Integer i3=128;
Integer i4=128;
System.out.println("i3.equals(i4):"+i3.equals(i4));
System.out.println("i3==i4:"+(i3==i4));
}
}
運行結果爲:
i1.equals(i2):true
i1==i2:true
i3.equals(i4):true
i3==i4:false
i1和i2沒有超過緩存的範圍,因此時同一個對象。i3和i4超過範圍了,因此會創建新對象。
Integer的緩存下限時-127,是固定的。但是上限是可以自己修改的。修改後的值不能小於127。如果小於,那麼修改無效。上限依然是127。
2.數組:在java中,數組也是一種類型,有成員變量和方法。多維數組中的元素爲低緯數組。Java中的數組可以不是矩陣數組。數組一經創建,其長度就不可改變。其內部的length時final修飾的。數組重寫了Object中的clone方法,x.clone()!=x。但是,數組的克隆是淺克隆,僅能保證clone()返回的數組與原數組的地址不同。如果數組中存放的是引用數據類型,那麼複製的數組中的元素依然指向相同的對象。
public class Maintest{
public static void main(String[] args) {
Super[] supers=new Super[2];
supers[0]=new Super();
supers[1]=new Super();
Super[] supers1=supers.clone();
System.out.println("supers1==supers:"+(supers1==supers));
System.out.println("supers1[1]==supers[1]:"+(supers1[1]==supers[1]));
}
}
運行結果:
supers1==supers:false//只保證引用的地址不一樣
supers1[1]==supers[1]:true//但內部的元素的引用都一樣。
高維數組複製時,內部元素的引用指向的對象(低緯數組)一樣。
數組輸出時,除了char類型以外,其餘都是調用了Object中的toString方法,輸出地址。
3.接口:接口中的方法都是abstract 修飾的,目的就是要類去實現它,實現多態調用。因此接口中不能聲明static修飾的方法,可以聲明static修飾的變量。如果有static修飾變量,那麼變量最好在聲明處賦初始值。當兩個接口中存在同名變量的時候,訪問時要加限定名稱。接口可以實現多繼承其他的接口,接口和接口之間不存在實現關係。綜上:
- 繼承關係可以存在類和類、接口和接口(多繼承)之間。
- 實現只能出現在類與接口之間。
4.嵌套類型:
靜態成員類:在類中定義了一個用static修飾的類,該類可以訪問外圍的private成員變量,但是如果是非靜態的,需要通過對象名來引用。
public class Maintest {
private String string="內部類的成員變量";
public static class staticclass{
public static void main(String[] args) {
System.out.println(new Maintest().string);//如果在類的內部,是可以直接通過對象名來訪問私有成員變量的
}
}
}
靜態類不依賴於外圍類的實例對象而存在。因爲是靜態,可以通過外圍類的類名來訪問。在訪問權限夠的情況下,靜態類可以繼承任何類,任何類也都可以繼承靜態類。
內部成員類:內部成員類必須通過對象來訪問,而靜態成員變量又是不需要對象可以直接通過類名來訪問。如果內部成員類中有靜態,會存在這樣的矛盾。因此內部成員類中不能聲明靜態(變量、方法、類、靜態初始化塊)。但是可以有final修飾的變量。
內部類綁定外圍類對象:創建內部類對象時,編譯器會爲內部類隱式聲明一個final修飾的外圍類引用,調用構造時,系統會傳參(外圍類對象)將該引用指向外圍類對象。
局部類:局部類是在方法、構造器、初始化塊中聲明的類,不能使用訪問權限修飾符來訪問,也不能使用static修飾。
上一篇 | ---The End--- |
... |