如何使用反射(Java)调用私有静态方法?
我想调用一个私有静态方法。我有它的名字。我听说它可以使用Java反射机制来完成。我怎么做如何使用反射(Java)调用私有静态方法?,java,reflection,invoke,Java,Reflection,Invoke,我想调用一个私有静态方法。我有它的名字。我听说它可以使用Java反射机制来完成。我怎么做 EDIT:我在尝试调用该方法时遇到的一个问题是如何指定其参数的类型。我的方法接收一个参数,其类型为Map。因此,我不能执行Map.TYPE(由于Java类型擦除,在运行时没有Map这样的事情)。是否有其他方法获取该方法?假设您想调用MyClass.myMethod(int x) 可能会引发许多已检查的异常。ParameterType和parameters都是椭圆参数(可变长度),请根据需要填写它们。JVMB
EDIT:我在尝试调用该方法时遇到的一个问题是如何指定其参数的类型。我的方法接收一个参数,其类型为Map。因此,我不能执行
Map.TYPE
(由于Java类型擦除,在运行时没有Map这样的事情)。是否有其他方法获取该方法?假设您想调用MyClass.myMethod(int x)
可能会引发许多已检查的异常。ParameterType和parameters都是椭圆参数(可变长度),请根据需要填写它们。JVMBY规范有一个强类型调用约定,因此您需要知道参数类型
话虽如此,除非您正在编写某种应用程序容器、服务器组件容器、类似RMI的系统或基于JVM的语言,否则您应该避免这样做。Invoke main from
import java.lang.reflect.InvocationTargetException;
导入java.lang.reflect.Method;
导入java.util.array;
公共类调用{
公共静态void main(字符串…参数){
试一试{
Class c=Class.forName(args[0]);
类[]argTypes=新类[]{String[].Class};
方法main=c.getDeclaredMethod(“main”,argTypes);
字符串[]mainArgs=Arrays.copyOfRange(args,1,args.length);
System.out.format(“调用%s.main()%n”,c.getName());
调用(null,(Object)mainArgs);
//生产代码应该更优雅地处理这些异常
}捕获(ClassNotFoundException x){
x、 printStackTrace();
}捕获(NoSuchMethodException x){
x、 printStackTrace();
}捕获(IllegalacessException x){
x、 printStackTrace();
}捕获(调用TargetException x){
x、 printStackTrace();
}
}
}
不,你不能说Map.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));
}
}
公共类调用程序{
/**
*获取方法并调用它。
*
*@作者jbetancourt
*
*@param方法的名称
*@param obj对象调用上的方法
*@param-types方法的参数类型
*@param args到方法调用
*@返回值
*@对不可见的东西抛出异常
*/
公共静态最终对象invokeMethod(最终字符串名,最终T对象,
最终类[]类型,最终对象…args)引发异常{
方法Method=obj.getClass().getDeclaredMethod(名称、类型);
方法setAccessible(true);
返回方法.invoke(obj,args);
}
/**
*嵌入式JUnit测试。
*/
@RunWith(JUnit4.class)
公共静态类调用测试{
/** */
@试验
public void testInvoke()引发异常{
类TestTarget{
私有字符串hello(){
返回“你好,世界!”;
}
}
String actual=(String)Invoker.invokeMethod(“你好”,
新TestTarget(),新类[]{});
字符串应为=“你好,世界!”;
(实际的、预期的)资产;
}
}
}谢谢。我的方法接收一个参数,其类型为Map。因此,我无法执行“Map.TYPE”。还有别的方法可以得到这个方法吗?@snakile:try
MyClass.class.getDeclaredMethod(“myMethod”,Map.class)
对于您的案例,如何更改(类、字符串等)。type?@deliver通常您可以使用YourClass.class
作为参数,Integer.type
只是基本类型的支柱,它们没有真正的类。但是,您如何获得该方法的返回值呢?因为它是静态的,所以不会保存在o
中代码>对于您的案例,有趣的是,该方法的通用信息在运行时仍然可用<代码>方法。getGenericParameterTypes
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
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();
}
}
}
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));
}
}