2010-09-02 58 views
3

可能重複:
What's the nearest substitute for a function pointer in Java?是否有與C++函數指針相當的Java?

我寫一個工廠類創建了一堆不同的小部件。爲了參數,假設這個工廠可以創建1000個小部件。

myWidget createWidget (widgetId) 
{ 
    case 0: createwidget0(); 
    . 
    . 
    case 1000: createwidget1000(); 
} 

我不想寫1000個case語句。我想將所有創建例程 放在一個數組中。使用widgetId作爲索引來直接執行create例程,所以 它不需要通過比較1000條件。所以整個createWidget 程序可以簡化,這樣

myWidget createWidget (widgetId) 
{ 
    myAwsomeFuncArr createFunc; 

    myWidget widget = createFunc[widgetId](); 
} 

有沒有去做到這一點在Java中?

+2

可能的重複:http://stackoverflow.com/questions/122407/whats-the-nearest-substitute-for-a-function-pointer-in-java – 2010-09-02 20:58:40

+0

你甚至不需要數組,嘗試getClass( ).getMethod( 「createwidget」 +爲widgetid).invoke();將取代你的案例/數組。 – 2010-09-04 07:57:11

回答

7

我很喜歡使用Java枚舉來完成這類任務。 一個乾淨的解決方案,嘿,類型安全!

public abstract class Widget { 
    protected boolean loaded; 

    public Widget() { 
     loaded = false; 
    } 

} 

public class ConcreteWidgetA extends Widget { 

    public ConcreteWidgetA() { 
     super(); 
    } 

    public void doSomething() { 
     if (!loaded) { 
     load(); 
     loaded = true; 
     } 
    } 

    private void load() { 

    } 

} 

public class ConcreteWidgetB extends Widget { 

    public ConcreteWidgetB() { 
     super(); 
    } 

    public void doSomethingElse() { 
     if (!loaded) { 
     load(); 
     load = true; 
     } 
    } 

    private void load() { 

    } 

} 

public enum Widgets { 

CONCRETE_WIDGET_A(new ConcreteWidgetA()), 
CONCRETE_WIDGET_B(new ConcreteWidgetB()); 

private Widget widget; 

public Widgets(Widget aWidget) { 
    widget = aWidget; 
} 

public Widget getWidget() { 
    return widget; 
} 

} 

public class WidgetFactory { 
    //Here's the money maker. 
    public static Widget createWidget(Widgets aWidgetElement) { 
    return aWidgetElement.getWidget(); 
    } 
} 
+0

這很有趣。這個解決方案並不容易理解爲Andreas提出的解決方案,儘管這可能是更好的選擇。我還得再學習一些。謝謝。 – tadpole 2010-09-02 21:32:28

+0

@tadpole,我覺得枚舉是Java最強大的功能之一。 :) – Mike 2010-09-02 21:36:59

+0

就像其中一些解決方案一樣好,我在他們身上看到一個Achille鞋跟。如果我錯了,請糾正我。這些解決方案預計將提前創建對象。我的問題是應用程序有100個對話框。其中一些對話框可能需要大量資源。他們不需要創建,直到他們需要。提前分配它們只是減少了資源並縮短了啓動時間。你有什麼建議嗎? – tadpole 2010-09-03 14:21:10

5

在Java中的函數指針的等效爲或算符

8

實現Widget工廠並將它們存儲在您的大數組中。這將是非常接近:

public interface WidgetFactory { 
    public Widget create(); 
} 

和別的地方:

public class MyClass { 
    private static Widgetfactory[] widgetFactories = new WidgetFactory[1000]; 
    static { 
    widgetFactories[0] = new FancyButtonFactory(); // FancyButtonFactory implements WidgetFactory 
    widgetFactories[1] = new FancyTextFieldFactory(); // see above 
    // ... 
    } 

    static public Widget createWidget(int index) { 
    return widgetFactories[index].create(); 
    } 
} 

這段代碼只寫不顯示函數指針一個類似的做法。真實生活中的應用程序將使用(更好)更好的設計。

+0

感謝安德烈亞斯,這與我的想法類似,但事先分配對象可能會造成問題,但我想我可以解決它。 – tadpole 2010-09-02 21:28:43

+0

最佳答案+1。我意識到這只是示例代碼,但我仍然好奇 - 爲什麼創建一個WidgetFactory類而不使用java.util.concurrent.Callable?是否有設計理由更喜歡一個比另一個? – emory 2010-09-03 00:59:18

+0

@emory - K.I.S.S. - 我試圖在問題中編寫一個非常簡單的「翻譯」給出的例子。 – 2010-09-03 04:29:28

1

A樣品函子:

public class Functor { 
interface func{ 
int fun(int x,int y); 
String toString(); 
} 
public static void main(String[] args) { 
    func add=new func(){ 
     public int fun(int x, int y) { 
      return x+y; 
     } 
     public String toString() { 
      return "+"; 
     } 
    }; 
    func mult=new func(){ 
     public int fun(int x, int y) { 
      return x*y; 
     } 
     public String toString() { 
      return "*"; 
     } 
    }; 
    func[] arr={add,mult}; 
    int i[]={10,20,30,40}; 
    for(int val:i) 
     for(func f:arr) 
     System.out.println(val+""+f+val+"="+f.fun(val,val));  

} 
} 

注意:如果你對1000級的小部件做這樣的事情,那麼你將作出1000匿名類files.I不知道它會影響性能。所以你最好在實施之前確保這一點。

我寧願選擇Andreas'sMikes's解決方案,以解決您的情況。