我有一个API,它接收$ javap -c IntegerIncrementTest.class
Compiled from "IntegerIncrementTest.java"
public class SO37056714.IntegerIncrementTest {
public SO37056714.IntegerIncrementTest();
Code:
0: aload_0
1: invokespecial #8 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: iconst_1
1: istore_1
2: iconst_3
3: istore_2
4: iload_1
5: iload_2
6: iadd
7: istore_1
8: return
}
并存储它以便稍后调用。为了调用它,我必须Method
。在我这样做之前,我想做一个防御性的副本。但是如何?
我想到了
setAccessible(true)
但是在桥接方法存在的情况下(或者两种方法具有相同名称/参数类型但返回类型不同的其他情况),这不一定会给我相同的方法。
我可以遍历method.getDeclaringClass()
.getDeclaredMethod(method.getName(), method.getParameterTypes());
并寻找完全匹配,但这似乎效率低下。
一个例子说明了为什么防御性副本可能会很好:
method.getDeclaringClass().getDeclaredMethod()
Method method = ...;
// Does setAccessible(true)
MyInvoker invoker = new MyInvoker(method);
// Sometime later, the user uses the same Method rather than re-retrieving it
method.setAccessible(true);
method.invoke(...);
method.setAccessible(false);
// Oops, now MyInvoker is broken
返回不同方法的示例:
getDeclaredMethod()
对我来说,打印:
interface Iface { Object get(); } class Impl implements Iface { @Override public String get() { return "foo"; } } for (Method method : Impl.class.getDeclaredMethods()) { System.out.println(method); System.out.println(copy(method)); System.out.println(); } private Method copy(Method method) { try { return method.getDeclaringClass() .getDeclaredMethod(method.getName(), method.getParameterTypes()); } catch (ReflectiveOperationException e) { throw new RuntimeException(e); } }
答案 0 :(得分:1)
你必须做你最初建议的事情,并依赖于Method#equals(Object)
的合同
将此
Method
与指定对象进行比较。如果,则返回true
对象是一样的。如果它们是两个Method
是相同的 由同一个类声明并具有相同的名称和形式参数 类型和返回类型。
因此您将无法使用getDeclaredMethod(String, Object...)
方法。您必须对Method[]
返回的getDeclaredMethods()
进行数组查找。例如,
private Method copy(Method method) {
Class<?> clazz = method.getDeclaringClass();
for (Method declaredMethod : clazz.getDeclaredMethods()) {
if (declaredMethod.equals(method)) {
return declaredMethod; // return the new one
}
}
throw new RuntimeException("This should not happen.");
}