java提高](18)—靜態內部類和非靜態內部類
定義
放在一個類的內部的類我們就叫內部類。
自己從開發到現在其實用到內部類主要在兩個地方會考慮用內部類:
1、使用靜態內部類的單例模式
2、將Json字符串轉為Bean實體的時候,也考慮創建內部類
其它比如網上說的通過內部類實現多繼承,我還沒有用過。這篇博客主要將靜態內部類和非靜態內部類中的成員內部類,至於局部內部類和匿名內部類這邊就不闡述了。
一、概念
我們可以簡單把內部類當成外部類的一個成員,如果你是static內部類,那么外部類不需要創建對象就可以訪問你,
如果你是非靜態類部類,那你就屬於外部類的對象的,所以一定要先創建外部對象才能來訪問你。
1、非靜態內部類
成員內部類也是最普通的內部類,它是外圍類的一個成員,所以它可以訪問外圍類的所有成員屬性和方法。同樣外圍類也可以訪問內部類的成員屬性和方法。
它的主要特點是:
1、成員內部類中不能存在任何static的變量和方法
2、成員內部類是依附於外圍類的對象,所以只有先創建了外圍類對象才能夠創建內部類對象
補充:對於成員內部內並不是完全不能出現static字段的,如果你是使用final和static同時修飾一個屬性字段,並且這個字段是基本類型或者String
類型的,那么是可以編譯通過的。至於原因需要了解class文件,我之前寫過一篇相關博客可以參考:【JVM虛擬機】(7)---深入理解Class中-屬性集合
2、靜態內部類
使用static修飾的內部類我們稱之為靜態內部類,我們要知道只要是static修飾的類那它一定是內部類
,不可能是外部類。
靜態內部類與非靜態內部類之間存在一個最大的區別,我們知道非靜態內部類在編譯完成之后會隱含地保存着一個引用,該引用是指向創建它的外圍類
的對象,但是靜態內部類卻沒有。沒有這個引用就意味着:
1、它的創建是不需要依賴於外圍類的對象
2、它不能使用任何外圍類的非static成員變量和方法
二、示例
有關靜態內部類和非靜態內部類這里做一個完整的代碼演示
1、代碼演示
/**
* 外部類 OutClass
*/
public class OutClass {
/**
* 外部類靜態屬性
*/
private static String name = "小小";
/**
* 外部類非靜態屬性
*/
private Integer age = 3;
/**
* @Description: 非靜態內部類
*/
private class InnerClass {
// TODO 非靜態內部類不能聲明或定義靜態成員
// private static String sex = "女";
/**
* 這里定義靜態常量是不會報錯的哦
*/
public static final String sex = "女";
/**
* 可以定義 普通屬性
*/
private int flag = 0;
/**
* 構造函數
*/
public InnerClass() {
// 非靜態內部類的非靜態成員可以訪問外部類的非靜態變量和靜態變量
System.out.println("非靜態類訪問外部對象的name" + name);
System.out.println("外部對象的age " + age);
}
}
/**
* @Description: 靜態內部類
*/
private static class InnerStaticClass {
/**
* 靜態內部類可以有靜態成員和非靜態成員
*/
private static String sex = "女";
private int flag = 0;
public InnerStaticClass() {
System.out.println("靜態類訪問外部對象的name" + name);
//靜態類只能訪問外部的靜態成員,不能訪問非靜態成員
//System.out.println("外部對象的age " + age);
}
}
public static void main(String[] args) {
System.out.println("==========非靜態內部類調用==========");
//new一個外部類
OutClass outClass = new OutClass();
// 通過外部類的對象new一個非靜態的內部類
OutClass.InnerClass innerClass = outClass.new InnerClass();
System.out.println("==========靜態內部類調用==========");
//獲取靜態內部類的靜態屬性
String sex = OutClass.InnerStaticClass.sex;
//獲取靜態內部類的非靜態屬性
OutClass.InnerStaticClass inner = new OutClass.InnerStaticClass();
System.out.println(inner.flag);
}
}
2、總結
這里在針對上面代碼做一個總結
1.靜態內部類可以有靜態成員(方法,屬性),而非靜態內部類則不能有靜態成員(方法,屬性)。
2.靜態內部類只能夠訪問外部類的靜態成員,而非靜態內部類則可以訪問外部類的所有成員(方法,屬性)。
3.實例化一個非靜態的內部類的方法:
a.先生成一個外部類對象實例
OutClass outClass=new OutClass();
b.通過外部類的對象實例生成內部類對象
OutClass.InnerClass inner=outClass.new InnerClass();
4.實例化一個靜態內部類的方法:
a.不依賴於外部類的實例,直接實例化內部類對象
OutClass.InnerStaticClass inner=new OutClass.InnerStaticClass();
b.調用內部靜態類的方法或靜態變量,通過類名直接調用
OutClass.InnerStaticClass.static_sex
補充
1、內部類的作用
我個人覺得主要有以下三點吧
1、內部類能夠提供更好的隱蔽性
。因為我們的內部類是可以用private和protected修飾的,所以在必要的時候我們可以保證在其它類里是
無法創建當前內部類對象的。就好比我們常用的靜態內部類的單例模式。
2、通過內部類可以實現多繼承
。
3、代碼可以更加整潔
。因為我們在創建實體類的時候,可能類中還包含其它類,如果這個類只會被當前類使用,那我們只需創建一個內部類就可以了。
2、展示一個靜態類部類的單例模式
/**
* 外部類
*/
public class StaticInnerSingleton {
/**
* 私有的靜態內部類
*/
private static class SingletonClassInstance{
private static final StaticInnerSingleton instance = new StaticInnerSingleton();
}
/**
* 獲取單例
*/
public static StaticInnerSingleton getInstance() {
return SingletonClassInstance.instance;
}
}
我相信,無論今后的道路多么坎坷,只要抓住今天,遲早會在奮斗中嘗到人生的甘甜。抓住人生中的一分一秒,勝過虛度中的一月一年!(4)