java - 使用基于反射的静态调用而不是接口(interface)

标签 java model-view-controller interface static-methods

我的问题是Java中的一般设计问题。在典型的基于 Controller 的设计中(比如 MVC), Controller 通常创建操作实例并调用从接口(interface)实现的方法(比如 Action 接口(interface)的execute())。

为什么我们需要创建不必要的对象,为什么不使用静态调用并消除实现接口(interface)的需要?

就像下面的例子。就像每个 Java 程序都应该有一个 main() 方法一样,每个操作方法都应该有一个execute()

class MyActionClass {
    public static void execute() {
        System.out.println("Hello from execute()!!");
    }
}

public class StaticTest {

    /**
     * @param args
     * @throws ClassNotFoundException
     * @throws SecurityException
     * @throws NoSuchMethodException
     * @throws InvocationTargetException
     * @throws IllegalArgumentException
     * @throws IllegalAccessException
     */
    public static void main(String[] args) throws ClassNotFoundException,
                        NoSuchMethodException, SecurityException, IllegalAccessException,
                        IllegalArgumentException, InvocationTargetException {
        Class<?> clazz = Class.forName("MyActionClass");
        Method method = clazz.getMethod("execute");
        method.invoke(null);
    }

}

最佳答案

因为反射 API 比使用反射时的方法调用慢得多,所以编译器无法进行任何优化,因为它无法真正了解您在做什么。

通过拥有一个接口(interface)和多个实现它的具体类,我们可以拥有多态行为的优势。添加Factory pattern在等式中,您可以直接使用您的接口(interface),而实际上不需要知道您正在调用哪个具体类方法。额外的好处是,编译器将能够优化您的代码,使其比使用反射 API 运行得更快。

从 Java 8 开始,我们可以在接口(interface)中实现静态方法和实例方法。这是一个演示:

public class InterfaceDemo
{
  public static void main(String... args)
  {
    XYZ.executeStatic("Hello");

    XYZ object = new Implementer();
    object.executeInstance("Message");
  }
}

interface XYZ
{
  static void executeStatic(String message)
  {
    System.out.println("Static: " + message);
  }

  default void executeInstance(String message)
  {
    System.out.println("Instance: " + message);
  }
}

class Implementer implements XYZ {}

然后是功能接口(interface),例如:

@FunctionalInterface
public interface Returnable<T>
{
  public T value();
}

它允许使用 lambda 表达式创建不同的实现,例如:

Returnable<Integer> integerReturnable = () -> 42;
Returnable<String> stringReturnable = () -> "Hello";

并使用类似:

System.out.println(integerReturnable.value()); // Prints 42
System.out.println(stringReturnable.value()); // Prints Hello

顺便说一下,如果需要创建的对象很多,我们使用 Object Pool pattern或类似的东西,如果有很多类似的对象,我们使用 Flyweight Pattern在保持速度的同时最大限度地减少内存使用。

关于java - 使用基于反射的静态调用而不是接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22434307/

相关文章:

java - Java中的非类函数

java - 为什么 IllegalArgumentException (JDK 1.4.2) 不能用可抛出的原因构造?

java - 将一个 ArrayList 的元素添加到另一个 ArrayList

objective-c - Cocoa中不同ViewController之间的通信

java - 如何在方法中使用带有 "fallback"参数的接口(interface)?

android - 模块间通信的最佳实践

java - 我如何在Java上检测声音频率

php - 业务逻辑和模板之间如何交互?

javascript - TypeScript 文件未加载或其他问题

pointers - 在 Golang 中将接口(interface)设置为 nil