2010-09-02 26 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解决方案,以解决您的情况。