java 内部类简单总结

在java中,一个类可以放在另一个类的内部,称之为内部类,相对而言,包含它的类称之为外部类
不过对于Java虚拟机而言,它是不知道内部类这回事的, 每个内部类最后都会被编译为一个独立的类,生成一个独立的字节码文件。
内部类可以方便的访问外部类的私有变量,可以声明为private从而实现对外完全隐藏,相关代码写在一起,写法也更为简洁。
在Java中,根据定义的位置和方式不同,主要有四种内部类:

  • 静态内部类
  • 成员内部类
  • 方法内部类
  • 匿名内部类

静态内部类
在外部类内部使用static关键字定义的类。可以有静态变量、静态方法、成员变量、成员方法和构造方法等,可以直接在静态内部类内部访问外部类的静态变量和方法。在其他地方需要通过

Outer.StaticInner os = new Outer.StaticInner();

的方式新建对象。

为什么不能访问外部类的实例变量和方法呢?这是因为内部类可以跟随外部类一起初始化进入方法区中,而此时外部类对象还不存在,实例变量也没有初始化,所以在静态内部类内部只能访问外部类的类(静态)属性和类方法

成员内部类
成员内部类没有static修饰符,也就是不能和外部类一起进行类的初始化,而是要依托于外部类的一个实例对象,所以成员内部类可以访问外部类的实例变量和方法。在外部使用时,它不能直接通过new Outer.Inner()的方式创建对象,而是要先将创建一个Outer类对象,如

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

与静态内部类不同,成员内部类中不可以定义静态变量和方法,如此规定的原因个人猜测是因为成员内部类是与外部实例相连的,使用内部类静态变量和方法的时候还必须持有一个外部类的对象,确实需要的话,也不如索性都挪到外部类中,可以省下一个外部类实例对象的空间开销。

方法内部类
在方法体内定义的类,只能在定义的方法内被使用。如果方法是实例方法,则除了静态变量和方法,内部类还可以直接访问外部类的实例变量和方法。可以直接访问方法的参数和方法中的局部变量,不过,这些变量必须被声明为final,之所以有这个限制的原因是方法内部类访问方法中的参数和局部变量是通过在编译器生成的构造方法中传递参数来实现的,实际上,方法内部类操作的并不是外部的变量,而是它自己的实例变量,只是这些变量的值和外部一样,对这些变量赋值,并不会改变外部的值,为避免混淆,所以干脆强制规定必须声明为final。值得注意的是,final修饰的不可变是指引用不可变,而非对象内容不可变。

匿名内部类
匿名内部类没有名字,在创建对象的同时定义类,直接使用new关键字new一个父类或者接口,然后覆盖相应的方法,就会生成相应的子类对象,语法如下:

new 父类(参数列表) {
//匿名内部类实现部分
}

或者

new 父接口() {
//匿名内部类实现部分
}

这里比较容易被忽略的就是匿名内部类也可以直接new一个类,虽然大多时候它被用来new接口来实现回调,比如最常用的Comparator。
匿名内部类只能被使用一次,用来创建一个对象。它没有名字,没有构造方法,但可以根据参数列表,调用对应的父类构造方法。它可以定义实例变量和方法,可以有初始化代码块,初始化代码块可以起到构造方法的作用,只是构造方法可以有多个,而初始化代码块只能有一份。
因为没有构造方法,它自己无法接受参数,如果必须要参数,则应该使用其他内部类。

原文地址:https://www.cnblogs.com/JackPn/p/9392182.html