内部类一直比较神秘,尤其是加上private、static修饰符以后,更加使人迷惑。但是看很多JDK源码里面都采用了此种设计。比如:ReferenceQueue中的lock、LinkedHashMap中的Entry。感兴趣的同学可以看一下这部份源码。
首先看一个例子:
内部类前加private修饰只有主类可以访问,这好解释。但是这几行代码编译不过。提示必须使用x.new A()的形式才可以访问。因为Inner类是一个非静态类,不允许直接实例化,需要依赖于主类的实例。
修改如下即可:
这样写不好的地方就是内部类的实例严重依赖于主类的实例的引用对象,写出来的代码很别扭。其实解决办法有两个。
第一种办法把Inner这个类提到主类的外部:
这种写法不好的地方在于Inner类的可以被其它类调用,这是我们不希望看到的。类的访问权限被放大了。
另一种写法是在Inner类的前加上static修饰符。这样可以就不依赖于主类实例化的引用对象了。
这种写法就是本文提倡的,LinkedHashMap巧妙的运用了这点,内部的每个Entry都是一个私有的静态内部类,该类继承了HashMap中的Entry。实际开发中我们也可以参照这种设计模式。
最后再提一下使用私内部静态类的单例模式。
该模式也使用到了上述提到的特点,只是直接使用内部类的属性而已。
首先看一个例子:
public static void main(String[] args) {
Inner inner1 = new Inner();
Inner inner2 = new Inner();
System.out.println(inner1);
System.out.println(inner2);
}
private class Inner { };
内部类前加private修饰只有主类可以访问,这好解释。但是这几行代码编译不过。提示必须使用x.new A()的形式才可以访问。因为Inner类是一个非静态类,不允许直接实例化,需要依赖于主类的实例。
修改如下即可:
public static void main(String[] args) {
Test1 t = new Test1();
Inner inner1 = t.new Inner();
Inner inner2 = t.new Inner();
System.out.println(inner1);
System.out.println(inner2);
}
private class Inner { };
这样写不好的地方就是内部类的实例严重依赖于主类的实例的引用对象,写出来的代码很别扭。其实解决办法有两个。
第一种办法把Inner这个类提到主类的外部:
public class Test1 {
public static void main(String[] args) {
Test1 t = new Test1();
Inner inner1 = new Inner();
Inner inner2 = new Inner();
System.out.println(inner1);
System.out.println(inner2);
}
}
class Inner { };
这种写法不好的地方在于Inner类的可以被其它类调用,这是我们不希望看到的。类的访问权限被放大了。
另一种写法是在Inner类的前加上static修饰符。这样可以就不依赖于主类实例化的引用对象了。
public class Test1 {
public static void main(String[] args) {
Test1 t = new Test1();
Inner inner1 = new Inner();
Inner inner2 = new Inner();
System.out.println(inner1);
System.out.println(inner2);
}
private static class Inner { };
}
这种写法就是本文提倡的,LinkedHashMap巧妙的运用了这点,内部的每个Entry都是一个私有的静态内部类,该类继承了HashMap中的Entry。实际开发中我们也可以参照这种设计模式。
最后再提一下使用私内部静态类的单例模式。
该模式也使用到了上述提到的特点,只是直接使用内部类的属性而已。
public class Test1 {
private Test1(){ }
public static Test1 getInstance()
{
return Inner.instance;
}
private static class Inner
{
private static Test1 instance = new Test1();
}
}