2013-10-22 42 views
7

我正在讀的書「Head First Java」,並在它提到一個內部類實例必須依賴於外部類的實例,這是我已經知道的,但是有一個例外中的某些點:在靜態方法中定義內部類的目的是什麼?

一個非常特殊情況-在靜態方法內定義的內部類。但是 你可能會去你的整個Java生活中,而不會遇到這些的 之一。

我很確定最後一條語句確實是真的,但是如果編譯器允許它發生,這意味着它存在的原因,否則它將是非法的Java。有人能告訴我一個這樣做會有用的例子嗎?

+3

它可以是一個匿名內部類?因爲那裏有很多。 –

+0

這是一個本地類,[JLS#14.3](http://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.3),不只是一個內部類。 – EJP

+0

@EJP但它*是一個內部類,所以它會符合問題的標準。 –

回答

3

它可能是特殊的,它可能不是。

你正在尋找一個方法中可用的本地類:內部類是匿名像

class Foo { 
    static void bar(){ 
     class MyRunnable implements Runnable { 
      public void run() { 
       System.out.println("No longer anonymous!"); 
      }  
     }; 
     Thread baz = new Thread(new MyRunnable()); 
    } 

} 

我見過的用途:

class Foo { 
    static void bar(){ 
     Thread baz=new Thread(new Runnable(){ 
      public void run(){ 
       System.out.println("quux"); 
      } 
     } 
    } 
} 

這在技術上是一個內部類(雖然是匿名的),並在靜態方法中定義。我個人會創建一個實現Runnable接口的靜態嵌套類,做:

baz = new Thread(new MyRunnable()); 

其中MyRunnable被定義爲:

class Foo { 
    static void bar(){ 
     // SNIP 
    } 
    static class MyRunnable implements Runnable { 
     public void run() { 
      System.out.println("No longer anonymous!"); 
     }  
    } 
} 
+1

如果您將「MyRunnable」移動到「bar」內,則與Fedeetz感興趣的方案完全相同。 –

+0

@MiserableVariable更新了第一個代碼塊。 – hexafraction

+0

它不會編譯,將'靜態類MyRunnable'改爲'class MyRunnable' –

1

有些人的看法是任何方法可以是靜態是靜態的。對於這樣的人來說,這個階級的內在美並不是非常重要的。

0

我不知道完整的上下文,但實用程序類中定義的閉包(即Guava的Function實現)和實現可能是一個示例。

但是,在搜索了一段時間後,我還沒有發現Guava本身的匿名封閉示例。

1

下面是一個靜態方法內部類的製造示例。它可以聲稱

  1. 它不需要靜態方法外被宣佈爲它在其他地方沒有要求
  2. 它應該是一個名爲類(即不是匿名的),因爲它被多次使用

    class Race { 
        public static void main(String[] args) throws Exception{ 
         class Runner implements Runnable { 
          final String name; 
          long time = -1; 
          Runner(String name) { this.name = name; } 
          public void run() { 
           try { 
            long start = System.currentTimeMillis(); 
            time = -2; 
            System.out.printf("Start %s\n", name); 
            for (int i = 0; i < 10; i++) { 
             Thread.sleep(1000); 
            } 
            System.out.printf("End %s\n", name); 
            this.time = System.currentTimeMillis() - start; 
           } catch (InterruptedException e) { 
            time = -3; 
           } 
          } 
          long time() { return time; } 
         }     
         Runner r1 = new Runner("One"); 
         Runner r2 = new Runner("Two"); 
         Thread one = new Thread(r1); 
         Thread two = new Thread(r2); 
         one.start(); 
         two.start(); 
         one.join(); 
         two.join(); 
         System.out.printf("One: %s, Two: %s\n", r1.time(), r2.time()); 
         System.out.printf("%s wins\n", r1.time() < r2.time() ? "one" : "two"); 
        } 
    } 
    
+0

感謝您的示例! – federicot

相關問題