顶层类只能处于Public跟默认访问级别. 而内部类可以处于任意访问级别.
A 实例内部类:
B 静态内部类:
局部内部类:
匿名类:
举例[实例内部类, 静态内部类]:
public class OnlyForTest { public static String staticOutMember = "Static Out Member"; private String userName; private int age; //省略Getter/Setter public static void main(String[] args) { OnlyForTest oft = new OnlyForTest(); //A1. 在创建实例内部类实例时, 外部类的实力必须已经存在. OnlyForTest.Inner inner = oft.new Inner(); //A3. 一个外部类可以有多个内部类 因此不允许外部类直接调用内部类方法或属性, 在需要时, 使用内部类实例访问内部类成员 //而内部类进对应一个外部类, 因此可以直接使用外部类的引用. oft.age = oft.new Inner2().age; inner.setOutInstanceNmae("tom"); oft.new Inner2().print(); //B1: 直接访问静态类静态成员, 不需创建实例. System.out.println(staticInnerClass.staticInnerMember); new staticInnerClass().printNmae(); } class Inner { public void setOutInstanceNmae(String s){ //A2. 实例内部类自动持有外部类实例的引用 userName = s; System.out.println("内部类直接引用外部类实例 - 内部类赋值外部类成员 " + userName); } }//end of class Inner class Inner2 { int age= 2; //A4. 在实例内部类中不能定义静态成员, 只能定义实例成员. //报错!static int staticInt = 4; public void print() { System.out.println(userName); //A5. 当内部类与外部类有同名的成员时,如age //直接使用age或shis.age表示inner2内age //OnlyForTest.this.age表示外部类中的age System.out.println(age); System.out.println(OnlyForTest.this.age); //B2. 直接访问外部类的静态成员 System.out.println(staticOutMember); } }//end of class Inner2 static class staticInnerClass { public static String staticInnerMember = "Static Inner Member"; public void printNmae() { //B3:静态内部类在访问外部类实例变量时, 必须通过外部实例 OnlyForTest o = new OnlyForTest(); o.userName = "set by Static Inner Class"; System.out.println(o.userName); } }//end of staticInnerClass }
编译后的Class文件:
DeCompiler之后 Inner的构造函数:
OnlyForTest$Inner2() { this$0 = OnlyForTest.this; super(); age = 2; }
可见, 每个inner实例都会自动包含一个外部类OnlyForTest的引用
而staticInnerClass类的构造函数为空, 因此他的实例不会自动引用外部类
从Decompile的Class文件来看, 对JVM来说, 无所谓内外类之分, 他们都是Class, 只是内部类会自动引用外部类实例 或是 其他特定的功能而已.
Servlet实践 2-2 <->
// Proudly powered by Apache, PHP, MySQL, WordPress, Bootstrap, etc,.