所谓内部类,就是在类内继续定义其他内部结构类。内部类的定义是相对的,一个类A定义在另一类B中,A称为内部类,B称为外部类。如果你想了解java的内部类别,你必须首先了解它Java内部类的详细分类,在学习内部类的过程中,这是非常重要的。
内部类别可以直接访问外部类别的成员。它的存在是为了加强包装,将内部类别放在外部类别中,其他类别不允许访问内部类别。同时,内部类别也增加了代码的维护,而不涉及其他类别。
一般来说,内部分为四类:
- 成员内部类
类似于成员变量,写在类中。如果内部类持有外部类的参考,可能会导致内部类没有执行,外部类无法释放,存在内存泄漏的风险。为了避免这种现象,内部对象的生命周期需要在外部对象的生命周期结束时手动结束。一般不需要特别注意,除非延迟回收会成为系统运维的瓶颈,GC机制通常足以应付。
实例:
class Circle {
double radius = 0;
public Circle(double radius) {
this.radius = radius;
}
/**
* 内部类
*/
class Draw {
public void drawSahpe() {
System.out.println("drawshape");
}
}
}
public static void main(String[] args) {
// 第一种方式
Outter outter = new Outter();
// Outtter对象必须创建
Outter.Inner inner = outter.new Inner();
// 第二种方式
Outter.Inner inner1 = outter.getInnerInstance();
}
}
class Outter {
private Inner inner = null;
public Outter() {
}
public Inner getInnerInstance() {
if(inner == null)
inner = new Inner();
return inner;
}
class Inner {
public Inner() {
}
}
}
可以拥有内部类 private 访问权限、 protected 访问权限、 public 访问权限和包括访问权限。
例如,如果成员的内部类别是上述例子 Inner 用 private 修改,只能在外部内部访问;如果使用 public 修改后,任何地方都可以访问;如果使用, protected 修改后,只能在同一包下或继承外部类别的情况下进行访问;若为默认访问权限,则只能在同一包下进行访问。
这和外部类有点不同。外部类只能被接受 public 和包访问两种权限修改。
就我个人而言,我明白,因为成员的内部类似乎是外部类的成员,所以他们可以有各种各样的权限来修改,比如类的成员。
- 静态内部类
在成员内部类别面前添加static。声明static类不持有外部类的引用,外部类的引用可以通过软引用保存,只有静态内部类不能造成内存泄漏。静态内部类不需要依赖外部类,这有点类似于类的静态成员属性,不能使用外部类的非 static 很容易理解成员变量或方法,因为如果允许访问外部类的非对象,可以在没有外部对象的情况下创建静态内部对象 static 成员会产生矛盾,因为外部类的非 static 成员必须附着在特定的对象上。
实例:
public class Test {
public static void main(String[] args) {
Outter.Inner inner = new Outter.Inner();
}
}
class Outter {
public Outter() {
}
/**
* 静态
*/
static class Inner {
public Inner() {
}
}
}
- 局部内部类
局部内部类是定义在一种方法或作用域的类。Inner2和Inner都是Outter的内部类。局部内部类就像方法中的局部变量,不能使用 public 、 protected 、 private 以及 static 修饰的。
实例:
class People{
public People() {
}
}
class Man{
public Man(){
}
public People getWoman(){
/**
* 局部内部类
*/
class Woman extends People{
int age =0;
}
return new Woman();
}
}
四、匿名内部类
匿名内部类是一种局部特殊情况,也应该是我们使用最多的。在编写事件监控代码时,使用匿名内部类不仅方便,而且使代码更容易维护。
实例:
class Test {
public static void main(String[] args) {
Thread thread = new Thread(
// 匿名内部类
new Runnable() {
@Override
public void run() {
System.out.println("Thread run");
}
}
);
}
}
同样,匿名内部类也不能访问修改符和 static 修饰符的。匿名内部类别是唯一一种没有结构的类别。匿名内部类的使用范围非常有限,因为它没有结构器。大多数匿名内部类用于接口回调。匿名内部类在编译过程中自动命名为Outter$1.class。一般来说,匿名内部类用于继承其他类别或实现界面,不需要添加额外的方法,只需要实现或重写继承方法。
通过上面的java内部类别的一目了然的分类介绍,相信大家对内部类别的分类已经很清楚了。只要你完全掌握了本文的精髓,面对内部类别的分类,你就会变得自信。