繁体   English   中英

使用基于反射的静态调用代替接口

[英]Using reflection based static invocation instead of interfaces

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

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

像下面的例子。 与每个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比使用反射时的方法调用慢得多,因此编译器无法进行任何优化,因为它无法真正了解正在执行的操作。

通过具有接口和实现它的多个具体类,我们可以拥有多态行为的优势。 在方程式中添加Factory模式 ,您可以直接使用您的接口,而无需真正知道您要调用哪种具体的类方法。 额外的好处是,与使用Reflection API相比,编译器将能够优化您的代码,使其运行更快。

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

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 {}

然后有一些功能接口,例如:

@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

顺便说一句,如果需要创建许多对象,则使用“ 对象池”模式或类似的对象,如果有很多相似的对象,则可以使用“ 飞行重量模式”来最小化内存使用,同时保持速度。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM