什么是靜態內部類?
有static關鍵字修飾的內部類。
比如:Pattern類中的Node類。
注意:
靜態內部類訪問外部類的靜態成員變量或方法必須是靜態的。
代碼:
public class Outer { private static String s1 = "this is s1 in Outer"; private static String s2 = "this is s2 in Outer"; public void method1() { // 外部類可通過內部類的對象調用內部類的私有成員變量或方法 System.out.println(new Inner().s1); System.out.println(new Inner().method2()); } private static String method2() { return "this is method2 in Outer"; } // 內部靜態類 public static class Inner { private String s1 = "this is s1 in Inner"; private static String s3 = "this is s3 in Inner"; public void method1() { // 內部類可直接訪問外部類的私有靜態成員變量或方法 System.out.println(s2); // 內部類和外部類有同名變量和方法時 System.out.println(s1); System.out.println(Outer.s1); System.out.println(method2()); System.out.println(Outer.method2()); } private String method2() { return "this is method2 in Inner"; } } }
調用:
public class MainClass { public static void main(String[] args) { Outer outer = new Outer(); System.out.println("------外部類測試--------"); outer.method1(); System.out.println("------內部類測試--------"); Outer.Inner inner = new Outer.Inner(); inner.method1(); } }
打印:
------外部類測試-------- this is s1 in Inner this is method2 in Inner ------內部類測試-------- this is s2 in Outer this is s1 in Inner this is s1 in Outer this is method2 in Inner this is method2 in Outer
分析:
反編譯后自動生成文件:Outer$Inner.class
Outer 反編譯代碼1:
public class jichu.Outer { private static java.lang.String s1; private static java.lang.String s2; static {}; public jichu.Outer(); public void method1(); private static java.lang.String method2(); static java.lang.String access$0(); static java.lang.String access$1(); static java.lang.String access$2(); }
Outer 反編譯代碼2:
public class Outer { private static String s1 = "this is s1 in Outer"; private static String s2 = "this is s2 in Outer"; public void method1() { System.out.println(new Inner().s1); System.out.println(new Inner().method2()); } private static String method2() { return "this is method2 in Outer"; } public static class Inner { private String s1 = "this is s1 in Inner"; private static String s3 = "this is s3 in Inner"; public void method1() { System.out.println(Outer.s2); System.out.println(this.s1); System.out.println(Outer.s1); System.out.println(method2()); System.out.println(Outer.access$2()); } private String method2() { return "this is method2 in Inner"; } } }
Outer$Inner 反編譯代碼1:
public class jichu.Outer$Inner { private java.lang.String s1; private static java.lang.String s3; static {}; public jichu.Outer$Inner(); public void method1(); private java.lang.String method2(); static java.lang.String access$0(jichu.Outer$Inner); static java.lang.String access$1(jichu.Outer$Inner); }
Outer$Inner 反編譯代碼2:
public class Outer$Inner { private String s1 = "this is s1 in Inner"; private static String s3 = "this is s3 in Inner"; public void method1() { System.out.println(Outer.access$0()); System.out.println(this.s1); System.out.println(Outer.access$1()); System.out.println(method2()); System.out.println(Outer.access$2()); } private String method2() { return "this is method2 in Inner"; } }
MainClass反編譯代碼:
public class MainClass { public static void main(String[] args) { Outer outer = new Outer(); System.out.println("------外部類測試--------"); outer.method1(); System.out.println("------內部類測試--------"); Outer.Inner inner = new Outer.Inner(); inner.method1(); } }
1、創建靜態內部類方式:Outer.Inner inner = new Outer.Inner();靜態內部類不依賴於外部類。
2、外部類可通過內部類的對象調用內部類的私有成員變量或方法。
3、靜態內部類訪問的外部類成員變量或方法為什么不能是非靜態的,而成員內部類可以?
成員內部類中Outer$Inner反編譯代碼1中有:
final jichu.Outer this$0; public jichu.Outer$Inner(jichu.Outer);
可以看出成員內部類中有外部類的引用,所以成員內部類對外部類的私有非靜態變量和方法可以隨意訪問。
從靜態內部類Outer$Inner反編譯代碼1中可以看出它不存在對外部類的引用,所以僅能訪問外部類的靜態成員變量或方法。
4、靜態內部類中可定義靜態的成員變量和方法。
總結
1、創建靜態內部類方式:Outer.Inner inner = new Outer.Inner();靜態內部類不依賴於外部類。
2、外部類可通過內部類的對象調用內部類的私有成員變量或方法。
3、靜態內部類訪問外部類的靜態成員變量或方法必須是靜態的。
4、靜態內部類中可定義靜態的成員變量和方法。
5、外部類可以創建靜態內部類的實例,即使是私有的;並可通過內部類的實例訪問內部類的成員變量和方法,即使是私有的。
