HengYk Blog

个人站

具有浪漫主义情调的理想主义务实青年


内部类解析

成员内部类

1.普通内部类可以使用任意的访问修饰符;

2.普通内部类可以访问Outer类中的对象,不受访问控制符的影响;

3.内部类 内部类对象 = 外部类对象.new 内部类();

    Outer out = new Outer();
    Inner inner = out.new Inner();

4.如果内部类和外部类的成员变量名字相同,则可以通过this指针来访问外部类成员变量。

    System.out.println(Outer.this.s);
public class Outer {

    // 外部类成员变量
    private int a = 99;

    private int s = 100;

    public class Inner {

        // 内部类成员变量
        int b = 2;

        int s = 100;

        public void test () {

            // 可以访问外部类对象的成员变量
            System.out.println(a);
            // 可以访问内部类对象的成员变量
            System.out.println(b);

            // 通过this指针来访问外部类的成员变量
            System.out.println(Outer.this.s);
        }
    }

    public static void main(String[] args) {

        Outer out = new Outer();
        Inner inner = out.new Inner();

        i.test();
    }
}
静态内部类

1.静态内部类不能直接访问外部类的非静态成员变量, 可以通过外部类对象.成员变量的方式;

    System.out.println(new Outer().a);

2.如果外部类的静态成员与内部类的静态成员相同;

    System.out.println(Outer.s);
    System.out.println(s);

3.创建静态内部类对象,不需要外部类的对象,可以直接创建。

    Inner inner = new Inner();
public class Outer {

    int a = 99;

    static int s = 0;

    static class Inner {

        int b = 2;

        static int s = 0;

        public void test {

            // 静态内部类不能直接访问非静态成员
            // System.out.println(a); // error
            System.out.println(new Outer().a);

            // 可以访问自己的内部类对象
            System.out.println(b);

            // 静态变量名重复,区别
            System.out.println(Outer.s);
            System.out.println(s);
        }
    }
}
方法内部类

1.方法内部类只能在外部类的方法中使用;

2.不能使用访问控制符和static。

public class Outer {

    public void test() {

        // 外部类方法中的常量
        final int a = 25;

        // 外部类方法中的局部变量
        int b = 13;

        class Inner {

            // 内部类方法中的成员变量
            int c = 2;

            public void print() {

                // 访问内部类的成员变量
                System.out.println(c);

                // 访问外部类方法的局部变量
                System.out.println(b);

                // 访问外部类方法的常量
                System.out.println(a);

            }
        }

        // 创建内部类的对象,调用内部类的方法
        Inner inner = new Inner();
        inner.print();
    }
}
为什么成员内部类可以访问外部类的成员

这里的内部类指的是普通成员内部类而非静态内部类

1 内部类对象的创建依赖于外部类对象;

2 内部类对象持有指向外部类对象的引用。

说明一:编译器自动为内部类添加一个成员变量, 这个成员变量的类型和外部类的类型相同, 这个成员变量就是指向外部类对象的引用;

final Outer this$0;

说明二:编译器自动为内部类的构造方法添加一个参数, 参数的类型是外部类的类型, 在构造方法内部使用这个参数为成员变量this$0赋值;

Outer$Inner(Outer);
为什么内部类可以访问外部类的私有成员
为什么外部类可以访问内部类的私有成员
static java.lang.String access$0(OuterClass);

当内部类调用外部类的私有属性(反之也一样)时,其真正的执行是调用了编译器生成的属性的静态方法(即acess$0,access$1等)来获取这些属性值。这一切都是编译器的特殊处理。