【2021-07-05】请说出内部类和静态内部类的区别?

225 阅读1分钟

请移步至 【DobbyKim 的每日一题】 查看更多的题目~

答:

普通内部类:

  • 可以访问外部类的所有属性和方法
  • 普通内部类中不能包含静态的属性和方法

静态内部类:

  • 静态内部类只能访问外部类的静态属性及方法,无法访问外部类的普通成员(变量和方法)
  • 静态内部类可以包含静态的属性和方法

那么,你知道为什么普通内部类可以访问到外部类的成员变量么?

我们来看一个示例:

Home

package com.github.test;

public class Home {

    class A {

    }
}

Home2

package com.github.test;

public class Home2 {

    static class A {

    }
}

执行编译后,我们来到 target 目录下,查看 Home 与 Home2 反编译的 class 文件

执行命令:

javap -private 'Home$A'

Home$A.class

class com.github.test.Home$A {
  final com.github.test.Home this$0;
  com.github.test.Home$A(com.github.test.Home);
}

执行命令:

javap -private 'Home2$A'

Home2$A.class

class com.github.test.Home2$A {
  com.github.test.Home2$A();
}

我们可以看到 Home 类当中含有普通内部类 A,对 class 文件反编译后,我们看到了一个特殊的字段:com.github.test.Home this$0;,这个字段是 JDK 为我们自动添加的,指向了外部类 Home。

所以,我们也就搞清楚了,之所以普通内部类可以直接访问外部类成员变量,是因为 JDK 为我么偷偷添加了一个隐式的变量 this$0,指向外部类。

那么,我们应该在什么时候使用内部类,什么时候使用静态内部类呢?

《Effective java》 第 24 条的内容是:Favor static member classes over nonstatic,即:优先考虑使用静态内部类。