我花了最后1或2个小时潜入Java反思。 我想我已经开始有了正确的理解。
然而,我无法找到一些我正在寻找的答案。我所了解的是,反射遭受了类查找的大(最大?)性能损失。
我有两个问题。
如何从当前上下文中调用方法(甚至可能?)? 在当前上下文中调用时,类查找的性能是否会被取消?
例如:
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是控制器并索引操作(通过反射调用的方法名称)。
如果你有充分的理由,为什么除了很多失败的机会之外绝对要避免这种情况,请告诉我。
我希望我的问题很明确。 感谢您花时间阅读,我期待着您的回复。
答案 0 :(得分:3)
不,遗憾的是,即使所有这些方法都在同一个实例上执行,也无法通过反射优化后续方法调用。其原因基本上是调用反射方法的签名:
// 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);
}
}
}
除此之外,我建议使用Reflection只有在它非常合理的情况下才会使用它,因为它会妨碍性能,更少类型安全并且还有一些其他缺点。如果一个人可以没有反思,就不应该使用它。
答案 1 :(得分:2)
如果我理解正确,你想为给定的字符串执行不同的代码部分。
我认为如果有更多"常规"我应该避免反思。这样做的原因只是因为更好的代码可读性。
考虑使用strategy pattern之类的东西。应该适合你的情况。
答案 2 :(得分:1)
如果你所做的只是调度到控制器方法,你绝对不应该担心性能。反射缓慢的整个问题是当你比较直接调用方法所需的1ns时,可能需要100ns查找+调用。顺便说一下,我更喜欢反思战略模式,但这两个确实非常接近,所以这是你的呼唤。
答案 3 :(得分:0)
与您调用方法的上下文没有区别,在所有情况下,您都以相同的方式执行此操作。您需要传递'this'对象来调用方法。
请注意:http://www.java2s.com/Code/Java/Reflection/CallamethoddynamicallyReflection.htm