Java內部類
內部類是什麼?
作爲包的成員的類被稱爲頂級類。一個類可以在另一個類中聲明。 這種類型的類稱爲內部類。
如果在另一個類中聲明的類被顯式或隱式聲明爲static
,它被稱爲嵌套類,而不是內部類。
包含內部類的類稱爲封閉類或外部類。
示例
下面的代碼聲明一個內部類。
class Outer {
public class Inner {
// Members of the Inner class go here
}
// Other members of the Outer class go here
}
Outer
類是一個頂級類。Inner
類是一個內部類。 它是外類的成員。Outer
類是Inner
類的封閉(外部)類。內部類可以是另一個內部類的封閉類。 內部類的嵌套層次沒有限制。
內部類的實例只能存在於其封閉類的實例中。
使用內部類的優點
以下是內部類的一些優點:
- 在使用它們的其他類中定義類。
- 提供了一個額外的命名空間來管理類結構。
- 一些設計模式使用內部類更容易實現。
- 實現回調機制使用內部類是優雅和方便的。它有助於在Java中實現閉包。
訪問局部變量的限制
下面的代碼演示了訪問局部內部類中的局部變量的規則。main()
方法聲明兩個局部變量:x
和y
。 這兩個變量都是被聲明爲 final
。變量x
在被初始化之後不能改變,變量y
也不能被改變,因爲它被聲明爲final
。
public class Main {
public static void main(String... args) {
final int x = 1;
final int y = 2;
class LocalInner {
void print() {
System.out.println("x = " + x);
System.out.println("y = " + y);
}
}
/*
* Uncomment the following statement will make the variable x no longer
* an effectively final variable and the LocalIneer class will not compile.
*/
// x = 100;
LocalInner li = new LocalInner();
li.print();
}
}
上面的代碼生成以下結果。
x = 1
y = 2
內部類和繼承
內部類可以繼承另一個內部類,頂級類或其封閉類。
class A {
public class B {
}
public class C extends B {
}
public class D extends A {
}
}
class E extends A {
public class F extends B {
}
}
內部類中沒有靜態成員
Java中的關鍵字static
使一個構造成爲一個頂層結構。因此,不能爲內部類聲明任何靜態成員(字段,方法或初始化器)。
允許在內部類中有作爲編譯時常量的靜態字段。
class A {
public class B {
public final static int DAYS_IN_A_WEEK = 7; // OK
public final String str = new String("Hello");
}
}
生成的內部類的類文件
每個內部類都被編譯成一個單獨的類文件。成員內部類和靜態內部類的類文件名格式如下:
<outer-class-name>$<member-or-static-inner-class-name>
本地內部類的類文件名的格式如下:
<outer-class-name>$<a-number><local-inner-class-name>
匿名類的類文件名的格式如下:
<outer-class-name>$<a-number>
類文件名中的<a-number>
是從1
開始順序生成的數字,以避免任何名稱衝突。
靜態上下文中的內部類
可以在靜態上下文中定義一個內部類,例如靜態方法或靜態初始化器。所有靜態字段成員都可以訪問這樣的內部類。
class Outer {
static int k = 1;
int m = 2;
public static void staticMethod() {
// Class Inner is defined in a static context
class Inner {
int j = k; // OK. Referencing static field k
// int n = m; // An error. Referencing non-static field m
}
}
}