局部内部类详解
什么是局部内部类?
定义在方法中的内部类。
注意:
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方式来访问外部类成员变量或方法。