public class InnerTest {
public static void main(String[] args) {
//必须先有外部类的对象才能生成内部类的对象,因为内部类的作用就是为了访问外部类中的成员变量
Outer.Inner in = new Outer().new Inner(); //out.new Inner()
in.show();
in.show1();
new Outer().show2();
new Outer().show3(166);
Test test = new Outer().getInnerPrivate();
test.test();
Test annoymous = new Outer().getAnonymous();
annoymous.test();
new Outer.InnerStatic().show();
}
}
interface Test {
public void test();
}
//外部类
class Outer {
private int age = 20;
private String name = "Outer.name";
private static String sex = "static.male";
//friendly内部类
class Inner {
//不能在非static内部类中持有static成员
//private static int aa = 1;
private int age = 30;
public void show() {
//内部类在没有同名成员变量和局部变量的情况下,内部类会直接访问外部类的成员变量,而无需指定Outer.this.属性名
System.out.println("内部类Inner直接访问外部类Outer的成员变量:" + name);
}
public void show1() {
int age = 40;
System.out.println("内部类Inner.show1()的局部变量:" + age);
System.out.println("内部类Inner成员变量:" + this.age);
System.out.println("内部类Inner指定Outer.this.属性名访问外部类成员变量:" + Outer.this.age);
}
}
//private内部类
//如果一个内部类只希望被外部类中的方法操作,那么可以使用private声明内部类
private class InnerPrivate implements Test {
private String innerPrivate = "inner private member";
private InnerPrivate() {}
private void show() {
System.out.println("私有内部类InnerPrivate的private方法show()");
}
public void test() {
System.out.println("私有内部类InnerPrivate的public方法test()访问外部类Outer的私有变量" + name);
}
}
//返回私有内部类的实例,在外部类的外面访问外部类的私有变量
public Test getInnerPrivate() {
return new InnerPrivate();
}
//在外部类内部,可以访问内部类的private成员
public void show2() {
new InnerPrivate().show();
}
//方法内部类
//方法内部类只能访问外部成员函数的final参数
public void show3(final int height) {
final int iValue = 100;
class InnerMethod {
public void show() {
System.out.println("方法内部类InnerMethod访问外部类方法Outer.show3()的final参数:" + height);
System.out.println("方法内部类InnerMethod访问外部类方法Outer.show3()的final局部变量:" + iValue);
System.out.println("方法内部类InnerMethod访问外部类Outer的成员变量:" + name);
}
}
new InnerMethod().show();
}
//匿名内部类
//内部类可以访问其他内部类的所有成员
public Test getAnonymous() {
final int iValue = 100;
return new Test() {
private String str;
private String name;
//一个实例初始化模块就是一个匿名内部类的构建器。缺点是不能重载。
{
this.str = "by anonymous class initial block";
this.name = "anonymous name";
if(this.str != null)
System.out.println("匿名内部类实例初始化:" + this.str + ", " + this.name);
}
public void test() {
System.out.println("匿名内部类的public方法test()访问外部类Outer的成员变量:" + Outer.this.name);
//访问在匿名内部类外部定义的一个对象,则编译器要求外部对象为final属性。
System.out.println("匿名内部类访问外部类方法Outer.getAnonymous()的final局部变量:" + iValue);
System.out.println("匿名内部类访问外部类的其他内部类Outer.InnerPrivate的私有成员:" + new InnerPrivate().innerPrivate);
}
};
}
//静态内部类
//静态内部类只能访问外部类的静态成员变量,可以直接用 new Out.InStatic()实例化
static class InnerStatic {
static int iValue = 1;
public void show() {
System.out.println("静态内部类InnerStatic访问外部类Outer的静态成员变量:" + sex);
}
}
}
* 所有的本地的、内部的、嵌套的和匿名的类都可以毫无限制地访问彼此的成员。
* 内部类可以随意使用外部类的成员变量(包括private)而不用生成外部类的对象,这也是内部类的唯一
优点。
* 普通(非内部)类不可设为private 或protected,只允许public 或者“友好的”。
* 非static内部类不可拥有static 成员或static 内部类。
* 内部类拥有对外部类所有成员的访问权限,持有Outer.this。
* 外部类拥有对内部类所有成员的访问权限, 在实例化内部类时,外部类实例会与内部类实例关联。
* 内部类拥有对其他内部类的所有成员的访问权限。
* 当我们从外部类继承的时候,没有任何额外的内部类继续下去。在继承类中使用同名内部类不会覆盖
基类的内部类,必须使用SubInner extends Parent.Inner。
* 方法内部类访问包围它的方法的参数和局部变量必须是final的,这是由于编译器会在方法内部类中创建
一个相同类型的final变量,并在内部类的构造器中,传入外部类的this对象和final参数,以便在外部方法
返回清空了方法栈的情况下仍然能够访问外部方法的变量(实际上访问的是传入的变量副本)。设置为
final的原因是为了数据保持一致性,如果不设置为final类型,那么在内部类中对该变量进行修改时,由于
内部类持有的是变量的副本,将会导致外部方法变量和内部类中持有的副本数据不一致,所以从逻辑上,
将外部方法变量和内部类副本同时设置为final,以保证数据的一致性。
输出为:
内部类Inner直接访问外部类Outer的成员变量:Outer.name
内部类Inner.show1()的局部变量:40
内部类Inner成员变量:30
内部类Inner指定Outer.this.属性名访问外部类成员变量:20
私有内部类InnerPrivate的private方法show()
方法内部类InnerMethod访问外部类方法Outer.show3()的final参数:166
方法内部类InnerMethod访问外部类方法Outer.show3()的final局部变量:100
方法内部类InnerMethod访问外部类Outer的成员变量:Outer.name
私有内部类InnerPrivate的public方法test()访问外部类Outer的私有变量Outer.name
匿名内部类实例初始化:by anonymous class initial block, anonymous name
匿名内部类的public方法test()访问外部类Outer的成员变量:Outer.name
匿名内部类访问外部类方法Outer.getAnonymous()的final局部变量:100
匿名内部类访问外部类的其他内部类Outer.InnerPrivate的私有成员:inner private member
静态内部类InnerStatic访问外部类Outer的静态成员变量:static.male