【问题标题】:Is there a Java equivalent to C++ function pointer? [duplicate]是否有与 C++ 函数指针等效的 Java? [复制]
【发布时间】:2011-04-07 13:38:22
【问题描述】:

可能重复:
What's the nearest substitute for a function pointer in Java?

我正在编写一个工厂类来创建一堆不同的小部件。为了论证起见,假设这个工厂可以创建 1000 个小部件。

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

我不想写 1000 个案例陈述。我想把所有的创建例程 在一个数组中。使用 widgetId 作为索引直接执行创建例程,所以 它不必经过比较1000个条件。所以整个 createWidget 例程可以这样简化

myWidget createWidget (widgetId)
{
    myAwsomeFuncArr    createFunc;

    myWidget widget = createFunc[widgetId] ();
}

在 Java 中可以做到这一点吗?

【问题讨论】:

标签: java


【解决方案1】:

我非常喜欢使用 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();
    }
}

【讨论】:

  • 这很有趣。这个解决方案不像 Andreas 提出的那样容易理解,尽管这可能是一个更好的选择。我得再学习一些。谢谢。
  • @tadpole,我觉得枚举是 Java 最强大的功能之一。 :)
  • 尽管其中一些解决方案很好,但我看到了其中的致命弱点。如果我错了,请纠正我。这些解决方案希望提前创建对象。我的问题是假设应用程序有 100 个对话框。其中一些对话框可能需要大量资源。在需要它们之前不需要创建它们。提前分配它们只会浪费资源并减慢启动时间。你有什么建议吗?
  • 这确实给我发布的设计带来了问题。你是对的,我正在预先分配资源。想到的一种选择是在请求时延迟加载小部件的真实内容。另一种是使用享元模式,尽管我认为它可能不太适用。我将更新我的代码以展示延迟加载如何提供帮助。
  • 我明白了。延迟加载是个好主意。我可以从这里拿走。无需您花费更多时间。谢谢。
【解决方案2】:

Java 中函数指针的等价物是function object 或仿函数。

【讨论】:

    【解决方案3】:

    实现小部件工厂并将它们存储在您的大数组中。那将非常接近:

    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();
      }
    }
    

    这段代码只是为了展示一个没有函数指针的类似方法。现实生活中的应用程序将使用(好得多)更好的设计。

    【讨论】:

    • 谢谢 Andreas,这与我的想法相似,虽然提前分配对象可能会带来问题,但我想我可以解决它。
    • 好答案 +1。我意识到这只是示例代码,但我仍然很好奇 - 为什么要创建一个 WidgetFactory 类而不使用 java.util.concurrent.Callable?是否有设计理由偏爱其中一个?
    • @emory - K.I.S.S. - 我只是尝试编写问题中给定示例的非常简单的“翻译”。
    【解决方案4】:

    一个示例函子:

    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 个匿名类文件。我不知道它是否会影响性能。所以你最好确认一下在实施之前。

    对于像您这样的情况,我更喜欢 Andreas's 或 Mikes's 解决方案。

    【讨论】:

      猜你喜欢
      • 2011-05-15
      • 2019-04-02
      • 2011-09-28
      • 2018-07-07
      • 2014-08-06
      • 2010-11-30
      • 2022-01-09
      • 2010-12-23
      • 1970-01-01
      相关资源
      最近更新 更多