今天刷题的时候遇到了一题关于内部类的访问的问题,发现本身忘了许多,如今来复习一下。
首先,内部类的类字节码文件名字为Outer$Inner.class。code
记住一下访问原则:
1.内部类至关于外部类的一个成员变量,所以内部类能够直接访问外部类的成员。可是注意内部类静态方法不能访问外部类非静态成员
2.可是外部类若是要访问内部类中的成员,要么内部类是静态的,跟着外部类一块儿被加载;要么建立内部类的对象,经过对象访问(想让外部类进内部类里面,总得有内部类的“实体”吧,这个“实体”要么是跟外部类一块儿加载的静态内部类,要么是新建的内部类的对象,不管是哪一种,都会在堆中为内部类开辟空间,而后才能够访问到)
例子:对象
a.外部类访问静态内部类的静态成员(一路畅通无阻) Outer.Inner.func(); b.外部类访问静态内部类的非静态成员(一路畅通到内部类门口, 发现里面还没东西,怎么办?建立对象!) //通常方式 Outer.Inner in = new Outer.Inner(); in.func(); //匿名方式 new Outer.Inner().func();//new Outer.Inner()建立出对象,而后调用对象的func c.外部类访问非静态内部类的非静态成员(没对象,内部类的门都找不到!乖乖一步步建立对象吧) //通常方式 Outer.Inner in = new Outer().new Inner(); in.func(); //匿名方式 new Outer().new Inner().func();
3.内部类若是有静态成员,则内部类也必须是静态的(不然内部类成员要随着外部类加载,发现内部类本身都还没加载,那这个成员是哪儿跑出来的呢?)
4.内部类访问局部变量时,局部变量必须加final修饰符。(随着方法运行完毕,局部变量会被释放,若是此时一个内部类还引用该变量则会报错。说到底就是变量的生命周期比内部类实例要短。而final保证这个变量始终指向一个对象,内部类就能够放心大胆地引用了。其实犯了和C++同样的毛病:返回了局部变量的引用)
注意:在JDK8版本之中,方法内部类中调用方法中的局部变量,能够不须要修饰为 final,匿名内部类也是同样的,主要是JDK8以后增长了 Effectively final 功能生命周期
class Outer{ public static void main(String[] args){ Object obj = new Outer().method(); } Object method(){ int locvar = 1; class Inner{ void displayLocvar(){ System.out.println("locvar = " + locvar); } } Object in = new Inner(); return in;//返回了内部类对象,可是该对象依然引用着局部变量 }
}class