我想調用一個私有靜態方法。我有它的名字。我聽說可以使用Java反射機制來完成。我該怎麼做?如何使用反射(Java)調用私有靜態方法?
編輯:我試圖調用該方法時遇到的一個問題是如何指定其參數的類型。我的方法接收一個參數,它的類型是Map。因此我不能這樣做Map<User, String>.TYPE
(在運行時,沒有像Java類型擦除那樣的Map之類的東西)。有另一種方法來獲得該方法嗎?
我想調用一個私有靜態方法。我有它的名字。我聽說可以使用Java反射機制來完成。我該怎麼做?如何使用反射(Java)調用私有靜態方法?
編輯:我試圖調用該方法時遇到的一個問題是如何指定其參數的類型。我的方法接收一個參數,它的類型是Map。因此我不能這樣做Map<User, String>.TYPE
(在運行時,沒有像Java類型擦除那樣的Map之類的東西)。有另一種方法來獲得該方法嗎?
假設你想調用MyClass.myMethod(int x);
Method m = MyClass.class.getDeclaredMethod("myMethod", Integer.TYPE);
m.setAccessible(true); //if security settings allow this
Object o = m.invoke(null, 23); //use null if the method is static
謝謝。我的方法接收一個參數,它的類型是Map
Object insecure; //This needs to be an initialized reference
Class c = insecure.getClass();
Method m = c.getMethod(name, parameterTypes); //Fill the name and types in
m.setAccessible(true);
m.invoke(insecure, parameters); //Fill in the parameters you would like
有許多檢查的異常可能拋出的。參數類型和參數都是橢圓參數(可變長度),根據需要進行填充。規範中的JVM具有強類型的調用約定,因此您需要知道參數類型。所以,除非你正在編寫某種應用程序容器,服務器組件容器,類似RMI的系統或基於JVM的語言,否則你應該避免這樣做。從reflection tutorial
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
public class InvokeMain {
public static void main(String... args) {
try {
Class<?> c = Class.forName(args[0]);
Class[] argTypes = new Class[] { String[].class };
Method main = c.getDeclaredMethod("main", argTypes);
String[] mainArgs = Arrays.copyOfRange(args, 1, args.length);
System.out.format("invoking %s.main()%n", c.getName());
main.invoke(null, (Object)mainArgs);
// production code should handle these exceptions more gracefully
} catch (ClassNotFoundException x) {
x.printStackTrace();
} catch (NoSuchMethodException x) {
x.printStackTrace();
} catch (IllegalAccessException x) {
x.printStackTrace();
} catch (InvocationTargetException x) {
x.printStackTrace();
}
}
}
調用主不,你不能說Map<K,V>.class
。這是因爲類型擦除。在運行時,沒有這樣的事情。
幸運的是,你可以說只是普通的舊Map.class
。運行時都是一樣的。
如果警告打擾您,請搜索與泛型和類型擦除有關的其他問題,這裏有關於此主題的大量信息。
我使用封裝獲取目標方法然後調用它的單個方法。當然可能有一些限制。這裏是放入類中的方法和它的JUnit測試:
public class Invoker {
/**
* Get method and invoke it.
*
* @author jbetancourt
*
* @param name of method
* @param obj Object to invoke the method on
* @param types parameter types of method
* @param args to method invocation
* @return return value
* @throws Exception for unforseen stuff
*/
public static final <T> Object invokeMethod(final String name, final T obj,
final Class<?>[] types, final Object... args) throws Exception {
Method method = obj.getClass().getDeclaredMethod(name, types);
method.setAccessible(true);
return method.invoke(obj, args);
}
/**
* Embedded JUnit tests.
*/
@RunWith(JUnit4.class)
public static class InvokerTest {
/** */
@Test
public void testInvoke() throws Exception {
class TestTarget {
private String hello() {
return "Hello world!";
}
}
String actual = (String) Invoker.invokeMethod("hello",
new TestTarget(), new Class<?>[] {});
String expected = "Hello world!";
assertThat(actual, is(expected));
}
}
}
嘗試`MyClass.class.getDeclaredMethod( 「myMethod的」,Map.class);`你的情況 – Cratylus 2011-01-22 21:05:59
有趣的是通用該方法的信息在運行時仍然可用。 `Method.getGenericParameterTypes` – 2011-01-23 11:11:35