访问特点:
内部类可以直接访问外部类的成员,包括私有成员。之所以课直接访问外部类中的成员,是因为内部类中持有了一个外部类的引用,格式 外部类名.this
而外部类要访问内部类中的成员必须要建立内部类的对象
1. 内部类的修饰符
public ,private static .......
当内部类的修饰符 为static时 ,此时,当外部类加载的时候,该内部类已经存在了。所以我们可以认为其是一个外部类。访问内部类时,不需要再new一个外部类的方式去访问,直接 Outer.Inner in = new Outer.Inner(); 当内部类中的成员也是静态的,那么久直接 Outer.Inner.function() ,注意: 如果内部类中定义了静态成员,那么该内部类必须是静态的。
2. 放在局部位置上的内部类。
class Outer{ int num =3; void method(){ final int x = 9; class Inner{ void show(){ //System.out.println("show ...." +num);// 可以访问到num System.out.println("show ...." +x); //想访问x,x必须为final型 } } // 此时想访问内部类的方法,只能再本方法中 创建内部类对象,用对象调用方法 Inner in = new Inner (); in.show(); } } public class InnerClassDemo{ public static void main(String[]args){ new Outer().method(); } }
请注意以下情况:
class Outer{ int num =3; Object method(){ final int x = 9; class Inner{ void show(){ //System.out.println("show ...." +num);// 可以访问到num System.out.println("show ...." +x); //想访问x,x必须为final型 } } // 此时想访问内部类的方法,只能再本方法中 创建内部类对象,用对象调用方法 Inner in = new Inner (); //in.show(); return in ; } } public class InnerClassDemo{ public static void main(String[]args){ Object obj = new Outer().method();// 多态 /** 当调用method时,该方法就进栈了,此时内存中多了个变量x ,创建对象并 赋值给in,最后返回给obj,方法就运算完了,就要出栈了,一出栈x就没了,但是obj还在, obj指向的inner对象中的show方法还在,但已经访问不到x了。但当x被final修饰时,变成了常量,此时x放入了常量池,不能被修改了。*/ } }
访问局部变量,该局部变量就要被定义为final类型,事实上,当存在有内部类时,经过编译之后,会产生两个class文件,内部类和外部类各一个,那么调用内部类的方法时怎么访问外部类的局部变量呢? 实际上,编译后的内部类的构造方法中传入了对应的外部类的引用和所有局部变量的形参。(由于外部类方法执行完后局部变量会消亡,所以内部类构造函数中的局部变量实际是一份“复制”。而为了访问外部类中的私有成员变量,外部类编译后也产生了访问类似与getXXX的方法。),所以如果不修饰为final,可能会造成内部类构造完成之后,外部类的局部变量的内容发生了改变,这是不被允许的。
3.匿名内部类
必须有前提: 内部类必须继承或者实现一个外部类或 接口。
匿名内部类,其实就是一个匿名子类对象 。
abstract class Demo{ abstract void show(); } class Outer{ public void method(){ new Demo(){ // 匿名内部类。 void show(){} } } }
4. 匿名内部类的具体应用。
通常的使用场景之一:
当函数参数是接口类型时,并且接口中的方法不超过3个,可以用匿名内部类作为实际参数,进行传递。
interface Inter{ void show1(); void show2(); } class Demo{ public static void main(String[]args){ show(new Inter(){ public void show1(){} public void show2(){} }) } public static void show(Inter in){ in.show1(); in.show2(); } }