內部類和靜態內部類


內部類和靜態內部類設計意圖##

參考原文地址:
https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html

首先看寫法:

class OuterClass {
	...
	static class StaticNestedClass {
    ...
	}
	class InnerClass {
    	...
	}
}

//使用上:
StaticNestedClass staticNestenClass = new OuterClass.StaticNestedClass();

OuterClass outerClass = new OuterClass();
InnerClass innerClass = outerClass.new InnerClass();

嵌套類分兩種:
一種是靜態的,英文更精確稱為static nested classes(靜態嵌套類).
一種是非靜態的, 英文稱為inner classes(內部類).

嵌套就是完全和外部類沒關系,只是寫在你里面。從使用上可以就看出來。在構造靜態嵌套類的時候外部類根本沒有new出來!只有靜態嵌套類存在!

內部類就不同。內部類就是外部類的一部分。有外部類才有內部類。內部類了解外面的全部。從使用上來說,內部類是以外部類對象存在為前提的!

下面是官網解釋:

A nested class is a member of its enclosing class. (inner classes) have access to other members of the enclosing class, even if they are declared private. Static nested classes do not have access to other members of the enclosing class.

As a member of the OuterClass, a nested class can be declared private, public, protected, or package private. (Recall that outer classes can only be declared public or package private.)
內部類修飾限定符作用按修飾限定符規則來。和嵌套不嵌套無關

為什么使用嵌套類?##

1.內部類就是為了外部類使用的,並且僅僅用於外部類的時候。這么做是為了代碼的包結構更好。

2.為了增加封裝性。有外部類A和內部類B兩個類。B要用A的私有變量,而且B自己也不被外部世界所見。

3.增加代碼可讀性。用到內部類的地方就是外部類!緊密兩個類的關系。好找代碼。

內部類不允許序列化!##

內部類絕對不允許序列化!java編譯器在編譯內部類的時候會生成一個虛擬的構造函數給內部類。編譯后這里面的所有內容在源碼里面不一定一一對應。這么做是為了讓java編譯器編譯后的代碼擁有源碼語法不具有的新特性。但是這種虛擬的構造函數在不同java編譯器上有差異。所以你序列化的時候是一個jre環境。反序列化的時候jre又是另一套環境。這可能導致兼容性問題。

內部類的特殊使用:匿名內部類和局部內部類##

局部內部類:

局部內部類可以定義在任何{}內,比如for if 方法體

注意:

局部內部類只能獲取外部{}中的final變量

從java8開始局部內部類可以訪問定義它的方法的參數。

內部類統一規則:內部不能有靜態變量和靜態方法!!!!

原因: 非static的內部類,在外部類加載的時候,並不會加載它,所以它里面不能有靜態變量或者靜態方法。static類型的屬性和方法,在類加載的時候就需要存在於內存中,你在內部類里寫的static JVM找不到!

方法塊中不能定義接口(因為接口隱含static修飾)

內部類不能有static變量。除非有final修飾(常量的加載不需要加載類)

匿名內部類是表達式!規則局部內部類

匿名內部類里可以的:
1.聲明成員變量

2.額外的方法。即使父類或者接口里沒有

3.初始化實例

4.聲明一個局部內部類

AClass aClass = new AClass() {
		private int a  = 1;

		class Fool {
			int getB() {
				return a+1;
			}
		}
		
		public int getB() {
			return a;
		}
		@Override
		public int geta() {
			// TODO Auto-generated method stub
			return new Fool().getB();
		}
		
	};

這么寫是正確的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM