JAVA嵌套类:静态嵌套类和非静态嵌套类
2024-08-24 01:45:36
1、内部类定义
内部类在维基百科的定义为: 面向对象编程中,内部类(又叫做嵌套类)是在另一个类或者接口中进行声明的类。内部类不同于子类(subclass)。(译者注:wiki的注解有误,内部类和嵌套类并不完全等同,详见下文。)
在Java中,上面的定义可以如下示例:
public final class Clazz {
private final class InnerClazz implements Runnable {
public InnerClazz() {
}
@Override
public void run() {
System.out.println("Hello world");
}
} public Clazz() {
}
public Runnable getRunnable(){
return new InnerClazz();
}
}
上面这个示例除了声明了一个内部类之外,没做其他任何事情。我举这个例子是想强调嵌套类和内部类的不同,因为不是所有的程序员都理解这一点。
2、内部类(Inner class)
上面的示例代码中声明了一个内部类“InnerClazz”。每次调用getRunnable方法的时候InnerClazz类的实例就会被创建出来。如果你在FindBugs中调试这段代码,你会看到下面这条警告信息: SIC:应该是个静态内部类(SIC_INNER_SHOULD_BE_STATIC) 。 这个类是一个由其外部对象创建的内部类,但是它没有使用内置的指向外部对象的引用。这个引用可以使得内部类实例更大,并且可以使得外部对象的生存期尽可能长。如果可能,这个类应该被定义成静态的。
这条警告信息很明确:内部类会保留一个指向其父类的引用,因此只要InnerClazz类被引用了,其父类就不能被JVM的垃圾回收机制自动垃圾回收(内部类和其父类的引用关系是很稳固的,你可以通过内存管理这篇文章了解更多)。如果你想使用这个引用,下面这种嵌套类是非常有用的:
1 public final class Clazz {
2 private final class InnerClazz implements Runnable {
3 public InnerClazz() {
4 }
5 @Override
6 public void run() {
7 // print the value of a member of its "parent" class
8 // it's possible because the inner class has an implicit reference
9 // on the Clazz instance
10 System.out.println(_currentNumber);
11 }
12 }
13 private int _currentNumber = 0;
14 public Clazz() {
15 }
16 public Runnable getRunnable() {
17 _currentNumber++;
18 return new InnerClazz();
19 }
20 }
3、非内部类的嵌套类(Nested but not inner class)
如果你并不需要保留Clazz实例和InnerClazz实例之间的非常稳固的引用关系,那么就将InnerClazz声明为一个静态成员类(下面的例子中的NestedNotInnerClazz类)。
1 public final class Clazz {
2 // static keyword is added
3 static private final class NestedNotInnerClazz implements Runnable {
4 public NestedNotInnerClazz() {
5 }
6 @Override
7 public void run() {
8 System.out.println("Hello world");
9 }
10 }
11
12 public Clazz() {
13 }
14 public Runnable getRunnable(){
15 return new NestedNotInnerClazz();
16 }
17 }
最新文章
- PowerDesigner逆向工程导入MYSQL数据库总结
- string类实现(C++)
- 闭包和this
- Android课程---Android Studio简单设置
- Linux生产服务器Shell脚本分享
- JS来操作hover
- VMWare虚拟机下RedHat 9.0linux的网络设置
- Verilog HDL中阻塞语句和非阻塞语句的区别
- BZOJ 1003 物流运输 (动态规划 SPFA 最短路)
- EF中的贪婪加载和延迟加载(懒加载)
- java 字符串反转
- AutoTile 自动拼接(六 大结局) 学习与实践
- MySQL——数据类型
- python面向对象之封装
- Python dict和set的实现原理
- 【GDOI2016模拟3.15】基因合成(回文串+性质+DP)
- Timeout occurred while waiting for latch: class 'ACCESS_METHODS_DATASET_PARENT'
- mybatis源码分析(四)---------------代理对象的生成
- python3 列表的赋值和深浅拷贝
- 原创:vsphere概念深入系列一:关于vsphere虚拟交换机的端口的数量限制。