我的问题是Java中的一般设计问题。在典型的基于控制器的设计中(比如说MVC),控制器通常会创建动作实例并调用从接口实现的方法(比如Action接口的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);
}
}
答案 0 :(得分:2)
好吧,因为Reflection API比使用反射时的方法调用慢得多,编译器无法进行任何优化,因为它对你正在做的事情没有真正的了解。
通过使用接口和实现它的多个具体类,我们可以获得多态行为的优势。在等式中添加Factory pattern,您可以直接使用接口,而无需实际需要知道要调用的具体类方法。额外的好处是,与使用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
顺便说一下,如果有很多对象需要创建,我们使用Object Pool pattern或类似的东西,如果有很多类似的对象,我们使用Flyweight Pattern来减少内存使用量同时仍保持速度。