我花了过去 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 开发。
我对框架等不感兴趣
因此,如果用户输入网址 http://www.hiurl.com/home/index
其中 home 是 Controller ,索引操作(反射调用的方法名称)。
如果您有充分的论据,为什么要绝对避免这种情况,除了很多失败的机会之外,也请告诉我。
我希望我的问题很清楚。 感谢您花时间阅读,我期待着阅读您的回复。
最佳答案
不,不幸的是,即使所有方法调用都在同一个实例上执行,也无法通过反射优化后续方法调用。其原因主要是调用反射方法的签名:
// in java.lang.reflect.Method
Object invoke(Object instance, Object... args);
// in java.lang.reflect.Field
Object get(Object instance)
使用反射优化调用唯一可以做的就是存储对 Method
、Field
、Constructor
等的引用,以便避免每次调用都进行昂贵的查找,例如:
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);
}
}
}
除此之外,我建议仅在有充分理由的情况下才使用反射,因为它会影响性能、类型安全性较差并且还有其他一些缺点。如果可以不用反射,就不应该使用它。
关于Java 反射从同一上下文调用方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11203140/