zoukankan      html  css  js  c++  java
  • JAVA嵌套类:静态嵌套类和非静态嵌套类

    1、内部类定义

      内部类在维基百科的定义为:  面向对象编程中,内部类(又叫做嵌套类)是在另一个类或者接口中进行声明的类。内部类不同于子类(subclass)。(译者注:wiki的注解有误,内部类和嵌套类并不完全等同,详见下文。)

      在Java中,上面的定义可以如下示例:

     1 public final class Clazz {
     2     private final class InnerClazz implements Runnable {
     3         public InnerClazz() {
     4         }           
     5         @Override
     6         public void run() {
     7             System.out.println("Hello world");         
     8         }   
     9     }     
    10     
    11     public Clazz() {
    12     }     
    13     public Runnable getRunnable(){
    14         return new InnerClazz();   
    15     } 
    16 }

      上面这个示例除了声明了一个内部类之外,没做其他任何事情。我举这个例子是想强调嵌套类和内部类的不同,因为不是所有的程序员都理解这一点。

    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 }
  • 相关阅读:
    SharePoint Error occurred in deployment step 'Recycle IIS Application Pool': 0x80070005:拒绝访问
    Getting SharePoint objects (spweb, splist, splistitem) from url string
    SharePoint 2010用“localhost”方式访问网站,File not found问题处理方式
    在 SharePoint 2010 打开网页出错时,显示实际的错误信息
    解决 SharePoint 2010 拒绝访问爬网内容源错误的小技巧(禁用环回请求的两种方式)
    SQL Server 删除数据库所有表和所有存储过程
    SQL Server 查询数据库表的列数
    SQL Server 自定义字符串分割函数
    sp_configure命令开启组件Agent XPs,数据库计划(Maintenance Plan)
    SQL Server 2008 收缩日志(log)文件
  • 原文地址:https://www.cnblogs.com/ChinaHook/p/4949805.html
Copyright © 2011-2022 走看看