内部类一直比较神秘,尤其是加上private、static修饰符以后,更加使人迷惑。但是看很多JDK源码里面都采用了此种设计。比如:ReferenceQueue中的lock、LinkedHashMap中的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();
}
}
分享到:
相关推荐
8.5.3 使用有多个形参的类模板 403 8.6 使用类 405 8.6.1 类接口的概念 405 8.6.2 定义问题 405 8.6.3 实现CBox类 406 8.6.4 定义CBox类 413 8.6.5 使用CBox类 423 8.7 组织程序代码 426 8.8 C++/...
CruiseYoung提供的带有详细书签... 8.6.3 使用有多个形参的类模板 405 8.6.4 函数对象模板 406 8.7 使用类 407 8.7.1 类接口的概念 407 8.7.2 定义问题 407 8.7.3 实现CBox类 408 8.8 组织程序代码 425 8.9 字符...
接口同私有实现分离 以及怎样定义并封装一个类的对象实例 这一章还有关于类域 嵌 套类 类作为名字空间成员的讨论 第 14 章详细讨论 C++为类对象的初始化 析构以及赋值而提供的特殊支持 为了支持 这些特殊的行为 ...
3.5.4 字符数据在内存中的存储形式及使用方法 41 3.5.5 字符串常量 41 3.5.6 符号常量 42 3.6 变量赋初值 42 3.7 各类数值型数据之间的混合运算 43 3.8 算术运算符和算术表达式 44 3.8.1 C运算符简介 44 3.8.2 算术...
3.5.4 字符数据在内存中的存储形式及使用方法 41 3.5.5 字符串常量 41 3.5.6 符号常量 42 3.6 变量赋初值 42 3.7 各类数值型数据之间的混合运算 43 3.8 算术运算符和算术表达式 44 3.8.1 C运算符简介 44 3.8.2 算术...
7.9.2 类的静态函数成员 334 7.10 类对象的指针和引用 334 7.10.1 类对象的指针 334 7.10.2 类对象的引用 337 7.11 c++/cli编程 338 7.11.1 定义值类类型 339 7.11.2 定义引用类类型 344 7.11.3 定义引用类类型的...
3.5 静态类...... 94 3.6 Object类...... 94 3.6.1 System.Object方法..... 94 3.6.2 ToString()方法..... 95 3.7 小结...... 97 第4章 继承.... 98 4.1 继承的类型...... 98 4.1.1 实现继承和接口继承..... 98 ...
在C语言中,输入输出是使用语句scanf()和printf()来实现的,而C++中是使用类来实现的。 #include iostream.h main() //C++中main()函数默认为int型,而C语言中默认为void型。 { int a; cout; cin>>a; /*输入...