前言
如果你是一个急性子,没什么耐性的人,可以只看下句,自己去品味理解:
内部类:就是我是你的一部分,我了解你,我知道你的全部,没有你就没有我。(所以内部类对象是以外部类对象存在为前提的)
静态内部类:就是我跟你没关系,自己可以完全独立存在,但是我就借你的壳用一下,来隐藏自己。
如果还不知道静态和普通成员的区别,就先学static吧。
静态成员:属于这个类,数据存放在class文件中,程序运行之前就已经存进去数据了。
普通成员:属于这个类的对象,程序运行后生成堆栈中。
先来看一下官方说法,根据Oracle官方的说法:
Terminology: Nested classes are divided into two categories: static and non-static. Nested classes that are declared static are called static nested classes. Non-static nested classes are called inner classes.
一个称为静态嵌套类(静态内部类),一个称为内部类。那么两者到底有什么区别呢?很多JDK源码用到了静态内部类。HashMap、ThreadLocal、AQS的sync等。那么接下来学习一下内部类吧!
内部类
内部类是定义在另外一个类中的类,主要原因有:
- 内部类方法可以访问该类定义所在的作用域中的数据,包括私有的数据
- 内部类可以对同一个包的其他类隐藏
静态内部类和非静态内部类最大的区别是:非静态内部类编译后隐式保存着外部类的引用(就算外部类对象没用了也GC不掉),但是静态内部类没有。
1.1 非静态内部类
1.1.1 定义
内部类定义语法格式如下:
class OuterClass { ... class NestedClass { ... } }
我们直接先看来一个例子吧,在Human类里定义了一个HumanLeg非静态内部类,并且在HumanLeg类的实例方法中直接访问外部类的private访问权限的实例变量和类变量。
/** * 人类 - 外部类 * * @author GrimMjx */public class Human { private static final int eyes = 2; private static void count() { System.out.println("I can count number"); } private int teeth = 10; private void say() { System.out.println("Hello world"); } /** * 人腿 - 非静态内部类 */ public class HumanLeg { private Double length; public HumanLeg(Double length) { this.length = length; } public void test() { say(); count(); System.out.println("I have " + eyes + " eyes"); System.out.println("I have " + teeth + " teeth"); System.out.println("My leg has " + length.toString() + "cm long"); } } public static void main(String[] args) { Human human = new Human(); HumanLeg humanLeg = human.new HumanLeg(100D); humanLeg.test(); } }
运行结果:
Hello world I can count number I have 2 eyes I have 10

