《内部类》学习笔记

内部类根据作用域可分为以下几类:
这里写图片描述
顶层类只能处于public和default访问级别,而成员内部类可以处于public、protected、private、default这4种级别。

实例内部类
实例内部类是成员内部类的一种,没有static修饰。实例内部类具有以下特点:
- 在创建实例内部类的实例时,外部类的实例必须已经存在;
- 实例内部类的实例自动持有外部类的实例的引用。在内部类中,可以直接访问 外部类的所有成员,包括成员变量和成员方法;
- 外部类实例与内部类实例之间是一对多的关系,一个内部类实例只会引用一个外部类实例,而一个外部类实例对应0个或多个内部类实例。在外部类中不能直接访问内部类的成员,必须通过内部类的实例去访问;
- 在实例内部类中不能定义静态成员,而只能定义实例成员;
- 如果实例内部类B与外部类A包含同名的成员(比如成员变量v),那么在类B中,this.v表示类B的成员,A.this.v表示类A的成员;

静态内部类
静态内部类是成员内部类的一种,用static修饰。静态内部类具有以下特点:
- 静态内部类的实例不会自动持有外部类的特定实例的引用,在创建内部类的实例时,不必创建外部类的实例;
- 静态内部类可以直接访问外部类的静态成员,如果访问外部类的实例成员,就必须通过外部类的实例去访问;
- 在静态内部类中可以定义静态成员和实例成员;
- 客户类可以通过完整的类名直接访问静态内部类的静态成员;

局部内部类
局部内部类时在一个方法中定义的内部类,它的可见范围是当前方法。和局部变量一样,局部内部类不能用访问控制修饰符(public、private和protected)及static修饰符来修饰。局部内部类具有以下特点:
- 局部内部类只能在当前方法中使用;
- 局部内部类和实例内部类一样,不能包含静态成员;
- 在局部内部类中定义的内部类也不能被public、protected和private这些访问控制修饰符修饰;
- 局部内部类和实例内部类一样,可以访问外部类的所有成员,此外,局部内部类还可以访问所在方法中的final类型的参数和变量;

子类与父类中的内部类同名
内部类并不存在覆盖的概念,假如子类与父类中存在同名的内部类,那么这两个内部类也会分别在不同的命名空间中,因此不会发生冲突。

匿名类
匿名类是一种特殊的内部类,这种类没有名字。匿名类具有以下特点:
- 匿名类本身没有构造方法,但会调用父类的构造方法;
- 匿名类尽管没有构造方法,但是可以在匿名类中提供一段实例初始化代码,Java虚拟机会在调用了父类的构造方法后,执行这段代码,如下例所示:

package com.test;

public class A {
    A(){
        System.out.println("default constructor !");
    }

    A(int v){
        System.out.println("anoth constructor !");
    }

    void method() {
        System.out.println("from A !");
    }
}

package com.test;

public class HelloWorld {
    public static void main(String[] args) {
        int v = 1;
        A a = new A(v) {
            {
                System.out.println("initialize instance !");    //实例初始化代码
            }

            void method() {
                System.out.println("from anonymous !");
            }
        };
        a.method();
    }           
}

由此可见,实例初始化代码具有和构造方法同样的效果,不过前者不允许被重载,匿名类的实例只能有一种初始化方式;
- 除了可以在外部类的方法内定义匿名类以外,还可以在声明一个成员变量时定义匿名类;
- 匿名类除了可以继承以外,还可以实现接口,Thread的匿名类就是很好的例子,实现了runnable接口;
- 匿名类和局部内部类一样,可以访问外部类的所有成员,如果匿名类位于一个方法中,还能访问所在方法的final类型的变量和参数;
- 局部内部类的名字在方法外是不可见的,因此与匿名类一样,能够起到封装类型名字的作用。

内部类的类文件
对于每个内部类来说,Java编译器会生成独立的.class文件。这些类文件的命名规则如下:
- 成员内部类:外部类的名字 数字 数字
例:

public class A {
    static class B {}       //成员内部类,对应A$B.class

    class C {               //成员内部类,对应A$C.class
        class D {}          //成员内部类,对应A$C$C.class
    }

    public void method1() {
        class E {}          //局部内部类1,对应A$1$E.class

        B b = new B() {};   //匿名类1,对应A$1.class
        C c = new C() {};   //匿名类2,对应A$2.class
    }

    public void method2() {
        class E {}          //局部内部类2,对应A$2$E.class
    } 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值