0

在过去的 1 到 2 个小时里,我一直在深入研究 Java 反射。我想我开始有了正确的理解。

但是,我找不到一些我正在寻找的答案。

我开始理解的是,反射在类查找中受到了很大的(最大的?)性能影响。

我有 2 个问题。

您如何从当前上下文中调用方法(甚至可能吗?)?在当前上下文中调用时,类查找对性能的影响会被抵消吗?

例如:

class User {
   private String name;

   public getName(){ return name; }
   public setName(String name){ this.name = name; }

   public void doSomething() {
       //some random stuff
       //I would like this method to invoke randomMethod();
       //Since it is within the same context(this)
       //Will this reduce the performance cost?

       //Please assume from my goals that I will ALWAYS know the name of the method i                  want to call.
      //So I wont need to loop through all available methods.

   }

   public void randomMethod() {

   }
}

我试图实现某种调度程序。例如用于 Java 中的 Web 开发。

我对框架等不感兴趣。

所以如果用户输入一个 url http://www.hiurl.com/home/index

其中 home 是控制器并索引操作(要通过反射调用的方法名称)。

如果您有充分的论据,除了失败的许多机会之外,为什么要绝对避免这种情况,也请告诉我。

我希望我的问题很清楚。感谢您花时间阅读,我期待阅读您的回复。

4

4 回答 4

3

不,不幸的是,即使所有方法调用都在同一个实例上执行,也无法通过反射优化后续方法调用。其原因基本上是调用反射方法的签名:

// in java.lang.reflect.Method
Object invoke(Object instance, Object... args);

// in java.lang.reflect.Field
Object get(Object instance)

使用反射优化调用的唯一方法是存储对 , 等的引用MethodFieldConstructor避免每次调用都进行昂贵的查找,例如:

public class User {

    public void methodToBeCalledUsingReflection() {
        // some logic
    }

    public void invocationWithPerformanceHit() {
        // lookup of Method instance - costly operation!
        Method method = User.class.getMethod("methodToBeCalledUsingReflection");
        // actual invocation of method
        method.invoke(this);
    }

    public void invocationWithoutPerformanceHit() {
        // only actual invocation of method
        method.invoke(this);
    }

    // moving Method instance to static field which is initialized (looked up) only once
    public static final Method method = getMethodReference("methodToBeCalledUsingReflection");

    private static Method getMethodReference(String methodName) {
        try {
            return User.class.getMethod(methodName);
        } catch(Exception ex) {
            throw new RuntimeException(ex);
        }
    }
}

除此之外,我建议仅在高度合理的情况下使用反射,因为它会妨碍性能,类型安全性较低并且具有其他一些缺点。如果可以不使用反射,则不应使用它。

于 2012-06-26T08:53:34.780 回答
2

如果我理解正确,您想为给定的字符串执行不同部分的代码。

我认为如果有更“常规”的方式来做这件事,你应该避免反思,这仅仅是因为代码可读性更好。

考虑使用类似策略模式的东西。在您的情况下应该可以正常工作。

于 2012-06-26T08:37:57.923 回答
1

如果您所做的只是调度到控制器方法,那么您绝对不应该担心性能。反射速度慢的整个问题是当您比较直接调用方法所需的 1ns 与查找 + 调用可能需要 100ns 时。顺便说一句,我更喜欢对策略模式进行反思,但这两者确实非常接近,所以这是你的决定。

于 2012-06-26T09:19:17.467 回答
0

与您要调用方法的上下文类型没有区别,在所有情况下,您都以相同的方式执行此操作。您需要将“this”对象传递给调用方法。

看:http ://www.java2s.com/Code/Java/Reflection/CallamethoddynamicallyReflection.htm

于 2012-06-26T08:41:26.547 回答