嵌套類是指定義在其他類裏面的類,其旨在爲外圍類提供服務。嵌套類有四種,分別爲靜態成員類、非靜態成員類、匿名類和局部類,其中非靜態成員類、匿名類和局部類又稱爲內部類。
靜態成員類
靜態成員類是最簡單的嵌套類。靜態成員類是外圍類的靜態成員,且和其他靜態成員一樣遵守相同的訪問規則。注意靜態成員類只能訪問外圍類的靜態成員。使用方法如下Demo
所示:
public class StaticMemberOfOutterDemo {
private int i = 1;
private static int j = 2;
public void out_f1() {
System.out.println("out_f1");
}
public static void out_f2() {
System.out.println("out_f2");
}
public static void out_f3() {
//內部類.屬性/方法
System.out.println(InnerStaticMember.k);
}
static class InnerStaticMember {
static int k = 3;
public void inner_f1() {
//不能訪問外圍類非靜態成員
//System.out.println(i);
System.out.println(j);
}
public void inner_f2() {
//不能訪問外圍類out_f1()
//out_f1();
out_f2();
}
}
}
非靜態成員類
與靜態成員類不同的是,非靜態成員類沒有使用static
修飾,且每個非靜態成員的實例都隱式地對應一個外部類的實例。成員內部類不能含有static
的變量和方法,但卻可以有static final
的變量。非靜態成員類可以訪問外部類中的任何變量或方法。
public class NonStaticMemberOfOutterDemo {
private int i = 0;
private static int j = 1;
private NonStaticMember member = new NonStaticMember();
public void out_f1() {
System.out.println(i);
System.out.println(j);
member.inner_f1();
member.inner_f2();
member.inner_f3();
}
public static void out_f2() {
}
class NonStaticMember {
int k = 2;
//不能聲明爲static
//static int l = 3;
static final int L = 3;
public void inner_f1() {
System.out.println(i);
System.out.println(j);
}
public void inner_f2() {
out_f1();
}
public void inner_f3() {
out_f2();
}
}
}
匿名類
顧名思義,匿名類就是沒有名字的內部類。若滿足以下條件,使用匿名類比較合適:
- 只用到類的一個實例
- 類在定以後馬上用到
- 類非常小(SUN
推薦是在4行以下)
- 給類命名並不會導致你的代碼更容易被理解
使用匿名類,注意以下幾個原則:
- 匿名類不能有構造方法
- 匿名類不能定義任何靜態成員、方法和類
- 匿名類不能是public
、protected
、private
和static
- 只能創建匿名類的一個實例
- 一個匿名類一定是在new
的後面,用其隱含實現一個接口或實現一個類
- 因匿名類爲局部類,所以局部類的所有限制都對其生效
局部類
局部類應該是使用最少的嵌套類。局部類可以和局部變量一樣,聲明在局部變量所在的任何地方,所以局部類不能有訪問說明符。但局部類可以訪問當前代碼塊內的常量和外圍類所有的成員。注意:
- 局部類只能在定義該內部類的方法內實例化,不可以在此方法外實例化
- ==局部類對象不能使用該內部類所在方法的非final
局部變量==(經實際測試,是可以調用)
public class LocalClassOfMethodDemo {
private int s = 100;
private int out_i = 1;
public void f(final int k) {
final int s = 200;
final int j = 10;
int i = 1;
class Inner {
int s = 300;
int inner_i = 100;
Inner(int k) {
//訪問外部類的屬性
System.out.println(out_i);
//訪問方法裏的局部變量
System.out.println(j);
//訪問方法裏的局部變量
System.out.println(i);
//訪問局部類中的變量
System.out.println(s);
//訪問局部類中的變量
System.out.println(this.s);
//訪問外部類中的屬性
System.out.println(LocalClassOfMethodDemo.this.s);
}
}
new Inner(k);
}
public static void main(String[] args) {
LocalClassOfMethodDemo localClassOfMethodDemo = new LocalClassOfMethodDemo();
localClassOfMethodDemo.f(3);
}
}
總結
以上四種嵌套類,每種都有各自的應用場景。如果內部類需要定義在方法之外或者類內容比較多,則使用內部成員類,至於是靜態還是非靜態,就看內部類是否需要獲取關聯的外部類實例,需要則爲非靜態成員類,否則反之。不過一般能用靜態成員類的就最好使用靜態成員類,畢竟非靜態都牽涉到個隱藏的實例,佔用資源。如果可以定義在方法內部,且只需使用一次則使用匿名類,否則使用局部類。