2009-09-11 57 views
2

這與Reflection類似,您可以通過其名稱簡單地調用方法,而不是預編譯的指針。如何在程序執行期間聲明一個函數?

就像在JavaScript中,您可以:

var fun = function(){ alert("Hello World!"); } 
fun(); 

是Java/J2ME類似的東西可能嗎?怎麼樣?

+1

'java.lang.reflect'類似於反射。或者可能是普通的舊式多態會更合適? – 2009-09-11 15:41:48

回答

2

如果你想爲J2ME的解釋,你可以檢查出HECL:http://www.hecl.org

你絕對不能做的大部分的「花哨」的東西,你可以在普通的Java J2ME中做。另一種方法是一系列的if/elseif,然後調用你想要的函數,但是你仍然需要提前知道,以便你可以編寫這樣的代碼。

1

您是在動態創建方法之後還是Reflection

您在Java中無法做到的第一件事,但您可以使用解釋器(如果您需要Java,則可以使用BeanShell)。

2

模仿此功能的一種方法是創建策略類。

interface Function 
{ 
    Object call(Object[] arguments); 
} 

做你的建議,簡單地做(更詳細一點,因爲Java通常是)以下:

static class Fun implements Function 
{ 
    public Object call(Object[] arguments) 
    { 
     System.out.println("Hello, world"); 
     return null; 
    } 
} 

Function fun = new Fun(); 
fun.call(null); 

根據不同的情況,你也許能夠用更好的類型或泛型而不是ObjectObject[](在這種情況下,我用它們來獲得最大的靈活性,但它們不會給你太多的類型檢查方式,所以它不是很理想)。

欲瞭解更多信息,請看strategy design pattern

1

至少有幾個方面:

你可以在運行時創建的類與BCEL,但你必須自己創建的字節碼。如果你的字節碼看起來不合適,JVM的驗證器可能會拒絕你的類。不是一個超級簡單的解決方案,但可行。

Sun的Java 6實現包括Rhino這個JavaScript解釋器,所以如果你願意使用一些JavaScript,你可以做你所需要的。

我對此不太確定,但我相信如果您安裝了JDK,則可以從Java程序中調用javacjavac的輸出可以在運行時用自定義的類加載。

2

得到類似Javascript的閉包的常用方法是使用匿名內部類。它更加冗長,但它可以讓你做幾乎相同的事情。

Runnable r = new Runnable(){ 
    public void run(){ 
     System.out.println("Hello, world!"); 
    } 
}; 
r.run(); // Prints "Hello, world!" 

你甚至可以引用變量在封閉的方法,如果他們最後:

public static Runnable makeGreeter(final String who) { 
    return new Runnable() { 
     public void run() { 
      System.out.println("Hello, " + who + "!"); 
     } 
    }; 
} 

// ... elsewhere in your program... 
Runnable r = makeGreeter("world"); 
r.run(); // "Hello, world!" 

這是標準的東西從一開始它已經在Java中。Runnable是一個非常方便的接口,根據Javadocs的說法,「應該由其實例旨在由線程執行的任何類來實現」。當然,Runnable可以用於比線程更多的地方,並且通常用於(在JVM和其他地方)作爲「可以執行的東西」 - 幾乎就像Javascript中的函數。當然,如果你想傳遞參數,你必須創建自己的接口,但也可以匿名實現。例如,使用@Imagist's Function interface

interface Function { 
    Object call(Object[] arguments); 
} 

// ... 
Function helloSayer = new Function(){ 
    public Object call(Object[] args){ 
     System.out.println("Hello, " + args[0] + "!"); 
    } 
}; 
helloSayer.call(new Object[]{ "world" }); // "Hello, world!" 

編輯:此無關與反思,當然,但有一個在你的榜樣要麼沒有反射 - 只是一個匿名函數。