【问题标题】:Interface to have dynamic method names具有动态方法名称的接口
【发布时间】:2020-08-10 00:28:52
【问题描述】:

假设一个接口是这样暴露的:

public interface IAction {
  void run();
  void walk();
  void stop();
  void jump();
}

现在像这样可以有任意数量的操作。每个动作都与一个枚举类型相关联,如下所示:

public enum Action {
  RUN("run"),
  WALK("walk"),
  STOP("stop"),
  JUMP("jump")
}

现在每次我想添加更多动作时,我都需要在 IAction 界面中添加一个枚举和关联方法。

相反, 无论如何,接口方法可以从枚举中公开吗? IAction 接口的任何实现都应该始终依赖于枚举 ActionAction 中的所有枚举类型都应该公开。这可能吗?

【问题讨论】:

  • 你是否打算对IAction进行不同的实现?
  • 假设我只有一个实现。那么有可能吗?无论如何,现在我不是在看多个实现。我认为不会有多个实现。这只是一个库,接口向客户端公开以使用这些方法。实现都在库中处理。
  • 如果你只有一个实现,那么你可以在你的枚举中设置实现。我将添加一个答案如何做到这一点。

标签: java reflection enums interface


【解决方案1】:

假设您只想有一个实现,您可以省略接口并在Action 中有一个Runnable,如下所示:

public enum Action {
  RUN("run", () -> System.out.println("run")),
  WALK("walk", () -> System.out.println("walk")),
  STOP("stop", () -> System.out.println("stop")),
  JUMP("jump", Action::jump);

  private final String value;
  private final Runnable action;

  Action(final String value, final Runnable action) {
    this.value = value;
    this.action = action;
  }

  public void execute() {
    action.run();
  }

  private static void jump() {
    // TODO: Implement me
  }

您可以对Runnable 使用lambda 或方法引用。调用者通过例如执行一个动作。 Action.RUN.execute()

这样你只需要在添加动作时更新这个类。

此示例类似于 Joshua Bloch 的 Effective Java,第三版中的第 42 项。

【讨论】:

  • 感谢您的解决方案。但我不是在寻找解决方法。我想知道Java是否有任何支持或任何方法可以在编译时动态实现方法名称。
  • 那你可能正在寻找反射:oracle.com/technical-resources/articles/java/…
  • 很公平。但是通过反射,我可以动态调用方法名称。但我的要求是在编译期间创建方法。就像 Lombok 库如何根据注释生成方法一样。同样,我需要从 IAction 类中从 Enum 类型生成所有可能的操作方法。
  • 我不确定我是否理解正确。通过反射,您可以遍历类的所有声明方法。
  • 如何动态声明方法?据我所知,我知道这不是编译器支持的东西。但我只是想知道是否有办法实现这一目标。
猜你喜欢
  • 2015-08-10
  • 2011-11-23
  • 2017-01-19
  • 2011-07-26
  • 2018-05-05
  • 2011-01-23
  • 2018-11-04
  • 2015-10-19
相关资源
最近更新 更多