非靜態內部類
非靜態內部類對象裏保存了一個它寄存的外部類對象的引用
- 存在非靜態內部類對象→則一定存在外部類對象
- 存在外部類對象→不一定存在非靜態內部類對象
規則:靜態成員不能訪問非靜態成員
- 注①:當外部類屬性、內部類屬性、內部類方法的局部變量都同名時
- 注②:不能直接訪問,必須顯示創建內對象
- 注③:不能在外部類的靜態成員(包括靜態方法和靜態初始化塊)中使用非靜態內部類,原因很簡單:非靜態內部類可看作是外部類的一個實例成員,而靜態成員不能訪問實例成員。
- 非靜態內部類裏不能有靜態屬性、靜態方法、靜態初始化塊
總之:外部類與非靜態內部類的”相互可見性“。
- 非靜態內部類可自由訪問外部類包括privated成員在內的所有成員,外部類也可通過創建內部類的對象來訪問其包括private成員在內的所有成員,所以它們雖然在類層面不是相互可見的,但是從廣義上來說具有相互可見性。
代碼分析
public class NonStaticInner {
class inner{
public void innermethod(){
System.out.println("innnermethod");
}
}
//外部類的非靜態方法訪問內部類
public void outermethod(){
new inner().innermethod();
}
/* 外部類的靜態方法訪問內部類(不能直接訪問)
* 因爲靜態不能訪問非靜態
* 只能必須先實例化外部類後實例化內部類才能訪問
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
NonStaticInner test =new NonStaticInner();
test.new inner().innermethod();
//test.outermethod();
}
}
靜態內部類
在定義靜態內部類的時候,是不需要定義綁定在外部類的實例上的。也就是說,要在一個外部類中定義一個靜態的內部類,不需要利用關鍵字new來創建內部類的實例
- 靜態內部類的對象只有外部類的類引用(沒有外部類對象的引用)
- 當靜態內部類的對象存在時→外部類對象不一定存在
- 注④:不能夠從靜態內部類的對象中訪問外部類的非靜態成員(包括成員變量與成員方法)
代碼分析
public class StaticInner {
String mNonString = "非靜態成員";
static String mString = "靜態成員";
//
static class inner{
int a = 1;
static int b = 2;
static void access(){
System.out.println(mString);
//System.out.println(mNonString);//錯誤,靜態不能訪問非靜態
System.out.println(new StaticInner().mNonString);
}
void nonaccess(){
System.out.println(mString);
//System.out.println(mNonString);//錯誤,即使是靜態內部類的實例方法,靜態也不能訪問非靜態
System.out.println(new StaticInner().mNonString);
}
}
//外部類的非靜態方法訪問內部類成員
public void outermethod(){
int c = inner.b;
int d = new inner().a;
}
public static void main(String[] args) {
//外部類的靜態方法訪問內部類成員
int c = inner.b;
int d = new inner().a;
//inner.access();
new inner().nonaccess();
}
}
兩者差別
- 如是否可以創建靜態的成員方法與成員變量(靜態內部類可以創建靜態的成員,而非靜態的內部類不可以)
- 對於訪問外部類的成員的限制(靜態內部類只可以訪問外部類中的靜態成員變量與成員方法,而非靜態的內部類即可以訪問所有的外部類成員方法與成員變量)
參考:
- JAVA靜態內部類用法
- Android 關於getView方法中ViewHolder類static修飾符
理解:①不管ViewHolder是靜態內部類還是非靜態內部類,都是一樣的實例化次數,即可見的item+1次(因爲都要new viewholder。)②內部類儘量使用static,是java規範(因爲靜態內部類不需要寄存外部類的引用this,減小內存開銷,降低內存泄漏)③但要注意使用靜態內部類的條件是內部類不需要訪問外部類