Java内部类是Java言语的一个很重要的概念。在阅读源码的时候发现使用了很多的内部类比如HashMap中的Node和ThreeNode。所以这里来整理一下并且总结归纳。
先说一下什么是内部类,把类定义在其他类的内部,那么这个类我们就称作内部类。它体现了一种代码的隐藏机制和访问控制机制。内部类与所在外部类有一定的关系,往往只有该外部类调用此内部类,所以没有必要专门用一个Java文件存放这个类。
内部类分为四种:静态内部类
、成员内部类
、局部内部类
、匿名内部类
。
1. 特点
静态内部类
public class TestClass {
private static int num1 = 1;
public static int num2 = 2; //私有
public static void main(String[] str) {
StaticInner staticInner = new StaticInner();
staticInner.test();
}
public static class StaticInner {
public void test() {
System.out.println("StaticInner: " + (num1 + num2));
}
}
}
静态内部类 (static inner class)
1.定义类时加上static关键字
2.不能和外部类名字相同
3.被编译成一个完全独立的.class文件(名称为OuterClass$InnerClass.class的形式)
4.只可以访问外部类的静态成员和静态方法,包括了私有的静态成员和方法。
5.生成静态内部类对象的方式为:OuterClass.InnerClass inner = new OuterClass.InnerClass();
成员内部类
public class TestClass {
private static int num1 = 1;
public static int num2 = 2; //私有
private int num3 = 3;
public int num4 = 4;
public static void main(String[] str) {
TestClass testClass = new TestClass();
TestClass.MemberInner memberInner = testClass.new MemberInner();
memberInner.test();
}
public class MemberInner {
public void test() {
System.out.println("MemberInner: " + (num1 + num2 + num3 + num4));
}
}
}
成员内部类 (member inner class)
1.静态内部类去掉static关键字就是成员内部类
2.成员内部类和静态内部类可以类比为非静态的成员变量和静态的成员变量
3.成员内部类就像一个实例变量
4.它可以访问它的外部类的所有成员变量和方法,不管是静态的还是非静态的都可以
5.在外部类里面创建成员内部类的实例:this.new Innerclass();
6.在外部类之外创建内部类的实例:(new Outerclass()).new Innerclass();
局部内部类
public class TestClass {
private static int num1 = 1;
public static int num2 = 2; //私有
private int num3 = 3;
public int num4 = 4;
public static void main(String[] str) {
TestClass testClass = new TestClass();
TestClass.MemberInner memberInner = testClass.new MemberInner();
memberInner.test();
}
public void test() {
final int num5 = 5;
class LocalInner {
public void test() {
System.out.println("LocalInner: " + (num1 + num2 + num3 + num4 + num5));
}
new LocalInner().test();
}
}
局部内部类 local inner class
1.局部内部类定义在方法中,比方法的范围还小。是内部类中最少用到的一种类型。
2.像局部变量一样,不能被public, protected, private和static修饰
3.只能访问方法中定义的final类型的局部变量
4.局部内部类在方法中定义,所以只能在方法中使用,即只能在方法当中生成局部内部类的实例并且调用其方法
匿名内部类
public class TestClass {
public static void main(String[] str) {
Long time = testClass.getDate(new Date());
System.out.println(time);
Long time2 = testClass.getDate(new Date() {
});
System.out.println(time2);
Long time3 = testClass.getDate(new Date() {
//重写父类中的方法
@Override
public long getTime() {
return 1000000000001L;
}
});
System.out.println(time3);
}
public Long getDate(Date date) {
return date.getTime();
}
}
//打印结果
1560417634298
1560417634298
1000000000001
匿名内部类 anonymous inner class
1.匿名内部类就是没有名字的局部内部类,不使用关键字class, extends, implements, 没有构造方法
2.匿名内部类隐式地继承了一个父类或者实现了一个接口
3.匿名内部类使用得比较多,通常是作为一个方法参数
4.生成的.class文件中,匿名类会生成OuterClass$1.class文件,数字根据是第几个匿名类而类推
2. 场景
上面介绍了4种内部类的特点,这里来介绍一下什么时候使用内部类,使用的场景又是哪些。
场景一:当某个类除了它的外部类,不再被其他的类使用时
场景二:解决一些非面向对象的语句块
场景三:一些多算法场合
场景四:适当使用内部类,使得代码更加灵活和富有扩展性