2011-03-22 74 views
39

這是我的代碼。Java是否支持inner/local/sub方法?

public class SubFunction { 
    private String drawTribleX(){ 
     return trible("X"); 
    } 
    private String trible(String t){ 
     return t + t + t; 
    } 
    public static void main(String[] args){ 
     SubFunction o = new SubFunction(); 
     System.out.println(o.drawTribleX()); 
    } 
} 

我可以這樣做嗎?

public class SubFunction { 
    private String drawTribleX(){ 
     // *** move trible(t) inside drawTribleX() *** 
     private String trible(String t){ 
      return t + t + t; 
     } 
     return trible("X"); 
    } 
    public static void main(String[] args){ 
     SubFunction o = new SubFunction(); 
     System.out.println(o.drawTribleX()); 
    } 
} 

謝謝。

+4

如果你已經將你的例子輸入到IDE中,它的編譯器就會告訴你答案。 – Bombe 2011-03-22 08:41:54

+0

[Java中的嵌套函數]可能的重複(http://stackoverflow.com/questions/7367714/nested-functions-in-java) – 2016-09-08 04:22:16

+4

@Bombe,不是真的。一個IDE本來可以確定OP是否可以完全做到這一點。如果你仔細閱讀,你會注意到問題是「我能做些什麼*這樣的事嗎?」 – aioobe 2016-11-13 15:22:21

回答

93

更新2014年2月9日:

JDK 8層推出的lambda(匿名函數表達式),它允許你解決這樣的:

Function<String, String> trible = s -> s+s+s; 
System.out.println(trible.apply("X"));   // prints XXX 

(JDK 7及以下)

不,Java確實不支持「直接」嵌套方法。 (儘管大部分功能語言都包含在內,包括一些JVM語言,如Scala和Clojure!)

僅供參考;您可以定義局部類(方法中的類),所以這編譯

class SubFunction { 
    private String drawTribleX(){ 

     // *** move trible(t) inside drawTribleX() *** 
     class Trible { 
      private String trible(String t){ 
       return t + t + t; 
      } 
     } 

     return new Trible().trible("X"); 
    } 
    public static void main(String[] args){ 
     SubFunction o = new SubFunction(); 
     System.out.println(o.drawTribleX()); 
    } 
} 

不過請注意,有一些restrictions on local classes

3.11.2。 上局部類限制

局部類受到以下限制:

  • 局部類僅在定義它的塊是可見的;它永遠不能在該塊之外使用。

  • 本地類不能被聲明爲public,protected,private或static。這些修飾符適用於類的成員;他們不允許使用局部變量聲明或局部類聲明。

  • 與成員類相似,出於同樣的原因,本地類不能包含靜態字段,方法或類。唯一的例外是聲明爲靜態和最終的常量。

  • 無法在本地定義接口。

  • 本地類,如成員類,不能具有任何其封閉類相同的名稱。

  • 如前所述,本地類可以使用局部變量,方法參數,甚至是在其範圍內的異常參數,但前提是這些變量或參數被聲明爲最終的。這是因爲本地類的實例的生命週期可能比定義該類的方法的執行時間長得多。出於這個原因,本地類必須擁有其使用的所有本地變量的私有內部副本(這些副本由編譯器自動生成)。確保局部變量和私人副本始終相同的唯一方法是堅持局部變量是最終的。

所以,你可以看到,你的第一個選項(沒有嵌套的方法)是在這些情況下,最好。

+11

保持此答案更新的主要+1。 – 2014-02-27 15:37:04

+0

「Trible」類內的'trible'方法可以是'static'嗎?這樣可以避免創建一個新的Trible()對象,因爲您只需調用靜態方法:Trible.trible(「X」)'。在相關的說明中,「Trible」類本身可以是「靜態」嗎?這會提供什麼優勢? – ADTC 2014-05-05 07:36:36

+1

不是,它位於3.11.2下的第二個項目符號中。 – aioobe 2014-05-05 07:51:31

6

很簡單 - 沒有。您不能在另一種方法中嵌套方法。

如果你真的要做到這一點,你可以定義方法中(奇怪的是,鑑於以前的限制),因此可以在外部方法中的類內包裝你的方法。

但是,這並不是非常習慣用法,一般的做法似乎是擁有一個私有方法列表(在頂級類中),也許根據目的和評論塊劃分組來劃分組。


如果你碰巧發現自己使用Scala的,但是,你可以嵌套方式離開你的心臟的內容...

1

你可以用這種方式嘗試以及它是匿名內部類。

public class SubFunction { 
    private String drawTribleX() { 
     // *** move trible(t) inside drawTribleX() *** 
     Trible t = new Trible() { 
      public String trible(String t) { 
       return t + t + t; 
      } 
     }; 
     return t.trible("X"); 
    } 

    public static void main(String[] args) { 
     SubFunction o = new SubFunction(); 
     System.out.println(o.drawTribleX()); 
    } 

    interface Trible { 
     String trible(String t); 
    } 
} 
0

您可以使用匿名類。像這樣的東西;

class SubFunction { 

    public static void main(String[] args) { 
     SubFunction o = new SubFunction(); 
     System.out.println(o.drawTribleX()); 
    } 

    private String drawTribleX() { 
     MyTrible trible = new MyTrible() { 
      @Override 
      public String doTrible(String t) { 
       return t + t + t; 
      } 
     }; 

     return trible.doTrible("X"); 
    } 

    private interface MyTrible { 
     public String doTrible(String t); 
    } 
} 

如果你想你可以定義不同類型的操作具有相同的接口,併爲你喜歡周圍傳遞這些。