什么是局部內部類?
定義在方法中的內部類。
注意:
1、內部類不能被public、private、static修飾;
2、在外部類中不能創建內部類的實例;
3、創建內部類的實例只能在包含他的方法中;
4、內部類訪問包含他的方法中的變量必須有final修飾;
5、外部類不能訪問局部內部類,只能在方法體中訪問局部內部類,且訪問必須在內部類定義之后。
代碼:
public class Outer { private String s1 = "this is s1 in Outer"; private String s_outer = "this is s_outer in Outer"; private String method1() { return "this is method1 in Outer"; } private String method2() { return "this is method2 in Outer"; } public void method3() { final String s_method = "this is s_method in method3"; class Inner { private String s1 = "this is s1 in Inner"; public void method1() { // 內部類訪問外部方法的變量,需要有final修飾 System.out.println(s_method); // 局部內部類可直接訪問外部類的變量,即使是私有的 System.out.println(s_outer); // 內部類和外部類有同名變量和方法時 System.out.println(s1); System.out.println(Outer.this.s1); System.out.println(method2()); System.out.println(Outer.this.method2()); } private String method2() { return "this is method2 in Inner"; } } Inner inner = new Inner(); inner.method1(); } }
調用:
public class MainClass { public static void main(String[] args) { Outer outer = new Outer(); outer.method3(); } }
打印:
this is s_method in method3 this is s_outer in Outer this is s1 in Inner this is s1 in Outer this is method2 in Inner this is method2 in Outer
分析:
反編譯后自動生成文件:Outer$1Inner.class
Outer 反編譯代碼1:
public class jichu.Outer { private java.lang.String s1; private java.lang.String s_outer; public jichu.Outer(); private java.lang.String method1(); private java.lang.String method2(); public void method3(); static java.lang.String access$0(jichu.Outer); static java.lang.String access$1(jichu.Outer); static java.lang.String access$2(jichu.Outer); }
Outer 反編譯代碼2:
public class Outer { private String s1 = "this is s1 in Outer"; private String s_outer = "this is s_outer in Outer"; private String method1() { return "this is method1 in Outer"; } private String method2() { return "this is method2 in Outer"; } public void method3() { String s_method = "this is s_method in method3";
Object inner = new Object() { private String s1 = "this is s1 in Inner"; public void method1() { System.out.println("this is s_method in method3"); System.out.println(Outer.this.s_outer); System.out.println(this.s1); System.out.println(Outer.this.s1); System.out.println(method2()); System.out.println(Outer.this.method2()); } private String method2() { return "this is method2 in Inner"; } }; inner.method1(); } }
Outer$1Inner反編譯代碼1:
class jichu.Outer$1Inner { private java.lang.String s1; final jichu.Outer this$0; jichu.Outer$1Inner(jichu.Outer); public void method1(); private java.lang.String method2(); }
Outer$1Inner反編譯代碼2:
class Outer$1Inner { private String s1 = "this is s1 in Inner"; Outer$1Inner(Outer paramOuter) {} public void method1() { System.out.println("this is s_method in method3"); System.out.println(Outer.access$0(this.this$0)); System.out.println(this.s1); System.out.println(Outer.access$1(this.this$0)); System.out.println(method2()); System.out.println(Outer.access$2(this.this$0)); } private String method2() { return "this is method2 in Inner"; } }
Outer$1Inner反編譯代碼1中有:
final jichu.Outer this$0; jichu.Outer$1Inner(jichu.Outer);
Outer 反編譯代碼1中有:
static java.lang.String access$0(jichu.Outer); static java.lang.String access$1(jichu.Outer); static java.lang.String access$2(jichu.Outer);
可知局部內部類可隨意訪問外部類的成員變量和方法,即使是私有的。(在成員內部類反編譯中也有同樣的代碼,詳見成員內部類詳解)
內部類和外部類有同名變量和方法時,需要通過Outer.this方式來訪問外部類成員變量或方法。
總結
1、內部類不能被public、private、static修飾;
2、在外部類中不能創建內部類的實例;
3、創建內部類的實例只能在包含他的方法中;
4、內部類訪問包含他的方法中的變量必須有final修飾;
5、外部類不能訪問局部內部類,只能在方法體中訪問局部內部類,且訪問必須在內部類定義之后。
6、可知局部內部類可隨意訪問外部類的成員變量和方法,即使是私有的。
7、內部類和外部類有同名變量和方法時,需要通過Outer.this方式來訪問外部類成員變量或方法。