Java内部类相关注意点

背景:
无论是看分布式、多线程相关源码,还是 Java编写 Spark、Flink相关大数据框架代码,都会遇到各种各样的内部类,今天复习下内部类相关注意点吧 ~

一、分类

静态内部类:定义在类内部的静态类
成员内部类:定义在类内部的非静态类
局部内部类:定义在方法中的类
匿名内部类:继承一个父类或者实现一个接口,没有class关键字,直接使用new来生成一个对象的引用

二、注意点汇总

1.对于成员内部类,必须先产生外部类的实例化对象,才能产生内部类的实例化对象。而静态内部类不用产生外部类的实例化对象即可产生内部类的实例化对象,不依赖于外部类。

2.静态内部类可以访问外部类所有的静态变量和方法,即使是 private 的也一样

3.其它类使用静态内部类需要使用“外部类.静态内部类”方式

4.成员内部类不能定义静态方法和变量(final 修饰的除外)。这是因为成员内部类是非静态的,类初始化的时候先初始化静态成员,如果允许成员内部类定义静态变量,那么成员内部类的静态变量初始化顺序是有歧义的

5.虽然成员内部类可以无条件地访问外部类的成员,而外部类想访问成员内部类的成员却不是这么随心所欲了。在外部类中如果要访问成员内部类的成员,必须先创建一个成员内部类的对象,再通过指向这个对象的引用来访问;如果要创建成员内部类的对象,前提是必须存在一个外部类的对象(也就是说成员内部类依赖于外部类的实例,可对比第一条)

6.局部内部类的访问仅限于方法内或者该作用域内

7.匿名内部类唯一一种没有构造器的类。正因为其没有构造器,所以匿名内部类的使用范围非常有限,大部分匿名内部类用于接口回调。匿名内部类在编译的时候由系统自动起名Outter$1.class。一般来说,匿名内部类用于继承其他类或是实现接口,并不需要增加额外的方法,只是对继承方法的实现或是重写

8.在JDK8之前,如果我们在匿名(局部)内部类中需要访问局部变量,那么这个局部变量必须用final修饰符修饰:

痛点: 方法执行完毕,那么定义在该方法内部的局部变量a也就结束了生命周期,但该方法内部的局部内部类或匿名内部类还没结束,可能还需要继续访问局部变量a,那么怎么办呢?

解决办法: 为了解决这个问题,java采用了复制局部变量的方式来达到目的!通过反编译可以看到,编译器默认会在匿名内部类常量池中添加一个内容与a相等的字面量,将其独立开;如果局部变量的值在编译期间就可以确定,则直接在匿名内部里面创建一个拷贝。如果局部变量的值无法在编译期间确定,则通过构造器传参的方式来对拷贝进行初始化赋值

新的问题: 那么采用副本复制的方式又会带来新的问题:因为匿名内部类中所使用的局部变量其实是编译器给内部类自己复制的副本,如果内部类副本局部变量为引用,和原变量都指向一个内存地址值,那么改变内部类局部变量是可能导致内外部类数据不一致,所以要加上final保证数据一致性

注意: 在JDK8之前是必须要加final的,但是JDK8做了优化,可以使用该局部变量不用加final,但实际底层还是自动添加了final!而且JDK8你如果不加final,但是你却对该局部变量做了修改,那么还是会编译错误Variable 'c' is accessed from within inner class,needs to be final or effectively final,所谓的effectively final,指的就是代码不加final底层优化帮加上!

9.创建的每个匿名内部类编译器都对应生成一个实现接口的子类,同时创建一个构造函数,构造函数的参数是外部类的引用,以及匿名函数中访问的参数 。所以匿名内部类不能有构造方法,只能有初始化代码块。 因为编译器会帮我们生成一个构造方法然后调用。

三、为什么要用内部类

使用内部类最吸引人的原因是:每个内部类都能独立地继承一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响。

在我们程序设计中有时候会存在一些使用接口很难解决的问题,这个时候我们可以利用内部类提供的、可以继承多个具体的或者抽象的类的能力来解决这些程序设计问题。可以这样说,接口只是解决了部分问题,而内部类使得多重继承的解决方案变得更加完整

相关特性:
1、匿名内部类可以用来创建多个实例,每个实例都有自己的状态信息,并且与其他外围对象的信息相互独立
2、在单个外部类中,可以让多个内部类以不同的方式实现同一个接口,或者继承同一个类。
3、创建静态内部类对象的时刻并不依赖于外围类对象的创建
4、内部类并没有令人迷惑的“is-a”关系,他就是一个独立的实体
5、内部类提供了更好的封装,除了该外围类,其他类都不能访问。
6、方便编写事件驱动多线程代码

    原文作者:深寒丶
    原文地址: https://blog.csdn.net/Abysscarry/article/details/88832837
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞