【Java】內部類
阿新 • • 發佈:2020-10-14
做題目時經常遇到,始終沒能完全搞清楚,這裡總結一下
內部分類:
- 成員內部類
- 靜態內部類
- 區域性內部類
- 匿名內部類
成員內部類
- 相當於外部類的一個成員變數,可以用任意訪問修飾符
- 定義的方法可以直接訪問外部類的資料,不受訪問控制符的影響,比如private
- 成員內部類的成員不能宣告為static的
- 在外部類的靜態成員使用內部類時,內部類要該為靜態內部類
- 編譯上述語句後產生兩個.class檔案:Outer.class,Outer$Inner.class{}
- 在內部類裡預設訪問自己的成員變數或方法,要訪問外部類的,用外部類物件.this.name
public class Outer{ private int age = 18; String name = "wang"; public class Inner{ String name = "wan"; //static String name = "wan";//不能使用static修飾成員變數和方法 public void method(){ System.out.println(Outer.this.name);//使用外部類成員:外部類名.this.成員 System.out.println(name);//預設使用內部類的成員 System.out.println(age);//內部類沒有的話就用外部類的 } } public Inner getInnerClass(){ return new Inner();//外部類要先建立內部類物件才能訪問內部類 } public static void main(String[] args){ Outer outer = new Outer(); Inner in = outer.new Inner();//內部類 物件名 = 外部類物件.new 內部類() in.method(); } }
靜態內部類
- 只能訪問外部靜態成員
- 屬於外部類本身,不屬於外部類某個物件
靜態內部類是不需要依賴於外部類的,這點和類的靜態成員屬性有點類似,並且它不能使用外部類的非static成員變數或者方法。
class Outter {
public static void main(String[] args) {
Outter.Inner inner = new Outter.Inner();
}
static class Inner {
public Inner() {}
}
}
靜態內部類實現延遲載入單例模式
靜態內部類和成員內部類一樣,都不會因為外部類的載入而載入,在使用時才載入。在載入靜態內部類時也會載入外部類。
public class SingletonIniti {
private SingletonIniti() {}
private static class SingletonHolder {
private static final SingletonIniti INSTANCE = neSingletonIniti();
}
public static SingletonIniti getInstance() {
return SingletonHolder.INSTANCE;
}
}
區域性內部類
-
其作用域僅限於方法內,方法外部無法訪問該內部類
-
不能有public、protected、private 以及 static 修飾符
-
只能訪問方法中的final的區域性變數,因為方法呼叫完了後就沒了,而區域性內部類還可以存在
在內部類中的屬性和外部方法的引數兩者從外表上看是同一個東西,但實際上卻不是,所以他們兩者是可以任意變化的, 也就是說在內部類中我對屬性的改變並不會影響到外部的形參,而然這從程式設計師的角度來看這是不可行的,畢竟站在程式的角度來看這兩個根本就是同一個,如果內部類該變了,而外部方法的形參卻沒有改變這是難以理解和不可接受的,所以為了保持引數的一致性,就規定使用 final 來避免形參的不改變
注意:在JDK8版本之中,方法內部類中呼叫方法中的區域性變數,可以不需要修飾為 final,匿名內部類也是一樣的,主要是JDK8之後增加了 Effectively final 功能
反編譯jdk8編譯之後的class檔案,發現內部類引用外部的區域性變數都是 final 修飾的
public class Outer{ public void Show(){ final int a = 25; int b = 13; class Inner{ int c = 2; public void print(){ System.out.println("訪問外部類:" + a); System.out.println("訪問內部類:" + c); } } Inner i = new Inner(); i.print(); } public static void main(String[] args){ Outer o = new Outer(); o.show(); } }
匿名內部類
new 類/介面{
//寫了一堆東西;
};
- 只能訪問區域性final變數(JDK8開始可以不用final,系統預設加了)
- 不能有構造方法
- 不能定義任何靜態的成員、方法
- 只能建立一個例項
- 必須且只能繼承一個類或者實現一個介面
public class OuterClass {
public InnerClass getInnerClass(final int num,String str2){
return new InnerClass(){
int number = num + 3;
public int getNumber(){
return number;
}
}; //注意:分號不能省
}
public static void main(String[] args) {
OuterClass out = new OuterClass();
InnerClass inner = out.getInnerClass(2, "chenssy");
System.out.println(inner.getNumber());
}
}
interface InnerClass {
int getNumber();
}