兩種內部類
Java的內部類有兩種,一種是靜態內部類,另一種是普通內部類,普通內部類可以獲得外部對象的引用,
所以在普通內部類能夠訪問外部對象的成員變量 ,也就能夠使用外部類的資源,可以說普通內部類依賴
於外部類,普通內部類與外部類是共生共死的,創建普通內部類的對象之前,必須先創建外部類的對象。
創建普通內部類的代碼如下:
Outer o = new Outer();
Outer.Inner inner = o.new Inner();
Outer.Inner inner = new o.Inner(); /* 錯誤 */
Outer.Inner inner = new Outer.Inner(); /* 錯誤 */
靜態內部類沒有外部對象的引用,所以它無法獲得外部對象的資源,當然好處是,靜態內部類無需依賴於
外部類,它可以獨立於外部對象而存在。創建靜態內部類的代碼如下:
Outer.Inner inner = new Outer.Inner();
靜態類的使用場景
在以下場合可以使用靜態內部類:
(1) 外部類需要使用內部類,而內部類無需使用外部類的資源
(2) 內部類可以獨立外部類創建對象
使用靜態內部類的好處是加強了代碼的封裝性以及提高了代碼的可讀性,舉個例子:
- public class Person{
- //姓名
- private String name;
- //家庭
- private Home home;
- //構造函數設置屬性值
- public Person(String _name){
- name = _name;
- }
- /* home、name的getter/setter方法省略 */
- public static class Home{
- //家庭地址
- private String address;
- //家庭電話
- private String tel;
- public Home(String _address,String _tel){
- address = _address;
- tel = _tel;
- }
- /* address、tel的getter/setter方法省略 */
- }
- }
把Home放在Person內部,一看便知道Home是Person的一個屬性。使用的時候也很方便,如下代碼:
- public static void main(String[] args) {
- Home home = new Person.Home("上海", "021");
- Person p1 = new Person("張三");
- Person p2 = new Person("李四");
- p1.setHome(home);
- p2.setHome(home);
- }
這裏創建一個home對象,p1和p2都使用這個home對象,p1和p2共享同一個home對象。
如果把Home換成普通內部類,情況就不同了,這時代碼變成:
- public static void main(String[] args) {
- Person p1 = new Person("張三");
- Home home = p1.new Home("上海", "021");
- p1.setHome(home);
- Person p2 = new Person("李四");
- p2.setHome(home);
- }
這裏p1和p2依然共享同一個home對象,但此時home對象和p1是同生共死的,如果p1對象消亡,那麼p2就沒有
家了,這對p2來說實在不公平,而如果爲p1和p2都創建一個Home對象,又浪費資源。所以在這個例子中,
使用靜態內部類比普通內部類要合適。
靜態內部類和普通內部類的區別
(1)普通內部類不能聲明static的方法和變量
普通內部類不能聲明static的方法和變量,注意這裏說的是變量,常量(也就是final static修飾的屬性)
還是可以的,而靜態內部類形似外部類,沒有任何限制。
(2)使用靜態內部類,多個外部類的對象可以共享同一個內部類的對象。
使用普通內部類,每個外部類的對象都有自己的內部類對象,外部對象之間不能共享內部類的對象