術語規範:按照官方文檔,定義在外部類(封裝類)內部的類稱之爲nested class,根據是否被static關鍵字修飾又分爲兩類:static nested classes 和 inner classes。閉包
class OuterClass { static class StaticNestedClass {} class InnerClass {} }
使用嵌套類的好處在於:this
當某個類爲旁類專用時,將其寫成嵌套類能使得代碼結構更緊湊。指針
嵌套類增長了封裝性code
內部類和靜態嵌套類的不一樣根源來自於static,最大區別在於訪問外部類成員的權限。對象
static修飾符使得嵌套類對象成爲外部類的靜態成員,與外部類直接關聯。作用域
這樣靜態嵌套類做爲一個靜態成員,僅能訪問外部類的靜態成員,由於外部類中的非靜態成員與外部類對象相關,靜態嵌套類就不能訪問他們,這使得靜態嵌套類的功能變的很弱,可用之處不多。文檔
另外由於靜態嵌套類是依附於外部類而非外部類對象的,因此不一樣的外部類對象共享一個靜態嵌套類,這一點與內部類不一樣,能夠用來包裝main方法。class
靜態嵌套類的聲明示例:變量
OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();
沒有static修飾意味着一個內部類是和外部類對象關聯的,也能夠說一個內部類對象存在於外部類對象中,是外部類對象的一個成員,所以內部類對象能夠訪問外部類對象的所有成員,包括私有成員。原理
由於內部類依賴於外部類對象而存在,因此不能定義任何靜態成員。
內部類對象能夠訪問外部類的全部成員變量,包括私有成員,這是Java閉包的原理;
由於內部類隱含對外部類的引用,因此外部類就不能被JVM的垃圾回收機制自動垃圾回收。
不一樣的外部類對象之間沒有公共的內部類對象成員。
內部類的聲明示例:
OuterClass.InnerClass innerObject = new OuterObject().new InnerClass();
嵌套類和封裝類以及局部方法區的變量做用域有重疊,若是有同名變量將發生變量遮蔽。
public class ShadowTest { public int x = 0; class FirstLevel { public int x = 1; void methodInFirstLevel(int x) { System.out.println("x = " + x); System.out.println("this.x = " + this.x); System.out.println("ShadowTest.this.x = " + ShadowTest.this.x); } } public static void main(String... args) { ShadowTest st = new ShadowTest(); ShadowTest.FirstLevel fl = st.new FirstLevel(); fl.methodInFirstLevel(23); } }
注意這裏對3種不一樣變量的引用方式,結果以下
x = 23 //1. 局部變量 this.x = 1 //2.內部類變量 ShadowTest.this.x = 0 //3.外部類變量
內部類中this指針指向內部類本身,ShadowTest.this則指向外部類對象;
不加修飾的變量,將執行就近匹配原則;若是名稱相同將發生變量遮蔽效應;爲了防止隱患,內部類引用外部類對象時應使用第三種方法。