如果我有两个变量:
Object obj; String methodName = "getName";
在不知道类的情况下obj
,如何调用其上标识的方法methodName
?
被调用的方法没有参数和String
返回值.它是Java bean的getter.
从臀部编码,它将是这样的:
java.lang.reflect.Method method; try { method = obj.getClass().getMethod(methodName, param1.class, param2.class, ..); } catch (SecurityException e) { ... } catch (NoSuchMethodException e) { ... }
参数标识了您需要的非常具体的方法(如果有多个重载可用,如果方法没有参数,则只给出methodName
).
然后通过调用调用该方法
try { method.invoke(obj, arg1, arg2,...); } catch (IllegalArgumentException e) { ... } catch (IllegalAccessException e) { ... } catch (InvocationTargetException e) { ... }
再次,.invoke
如果你没有参数,请省略参数.但是,是的.阅读Java Reflection
使用反射中的方法调用:
Class> c = Class.forName("class name"); Method method = c.getDeclaredMethod("method name", parameterTypes); method.invoke(objectToInvokeOn, params);
哪里:
"class name"
是类的名称
objectToInvokeOn
是Object类型,是要调用方法的对象
"method name"
是您要调用的方法的名称
parameterTypes
是类型Class[]
并声明方法采用的参数
params
是类型Object[]
并声明要传递给方法的参数
对于那些想要在Java 7中使用直接代码示例的人:
Dog
类:
package com.mypackage.bean; public class Dog { private String name; private int age; public Dog() { // empty constructor } public Dog(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public void printDog(String name, int age) { System.out.println(name + " is " + age + " year(s) old."); } }
ReflectionDemo
类:
package com.mypackage.demo; import java.lang.reflect.*; public class ReflectionDemo { public static void main(String[] args) throws Exception { String dogClassName = "com.mypackage.bean.Dog"; Class> dogClass = Class.forName(dogClassName); // convert string classname to class Object dog = dogClass.newInstance(); // invoke empty constructor String methodName = ""; // with single parameter, return void methodName = "setName"; Method setNameMethod = dog.getClass().getMethod(methodName, String.class); setNameMethod.invoke(dog, "Mishka"); // pass arg // without parameters, return string methodName = "getName"; Method getNameMethod = dog.getClass().getMethod(methodName); String name = (String) getNameMethod.invoke(dog); // explicit cast // with multiple parameters methodName = "printDog"; Class>[] paramTypes = {String.class, int.class}; Method printDogMethod = dog.getClass().getMethod(methodName, paramTypes); printDogMethod.invoke(dog, name, 3); // pass args } }
输出:
Mishka is 3 year(s) old.
您可以通过以下方式调用带有参数的构造函数:
Constructor> dogConstructor = dogClass.getConstructor(String.class, int.class); Object dog = dogConstructor.newInstance("Hachiko", 10);
或者,您可以删除
String dogClassName = "com.mypackage.bean.Dog"; Class> dogClass = Class.forName(dogClassName); Object dog = dogClass.newInstance();
并做
Dog dog = new Dog(); Method method = Dog.class.getMethod(methodName, ...); method.invoke(dog, ...);
建议阅读: 创建新类实例
可以像这样调用该方法.还有更多的可能性(检查反射api),但这是最简单的:
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import org.junit.Assert; import org.junit.Test; public class ReflectionTest { private String methodName = "length"; private String valueObject = "Some object"; @Test public void testGetMethod() throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException { Method m = valueObject.getClass().getMethod(methodName, new Class[] {}); Object ret = m.invoke(valueObject, new Object[] {}); Assert.assertEquals(11, ret); } }
首先,不要.避免使用这种代码.它往往是非常糟糕的代码和不安全的(参见Java编程语言安全编码指南第2节,版本2.0).
如果你必须这样做,那就选择java.beans来反思.豆包裹反射允许相对安全和传统的访问.
为了完成我同事的答案,您可能需要密切关注:
静态或实例调用(在一种情况下,您不需要该类的实例,在另一种情况下,您可能需要依赖现有的默认构造函数,可能存在也可能不存在)
公共或非公共方法调用(对于后者,您需要在doPrivileged块中的方法上调用setAccessible,其他findbugs将不满意)
如果你想要抛弃大量的java系统异常(因此下面的代码中的CCException),则封装成一个更易于管理的应用程序异常
这是一个旧的java1.4代码,它考虑了这些点:
/** * Allow for instance call, avoiding certain class circular dependencies.
* Calls even private method if java Security allows it. * @param aninstance instance on which method is invoked (if null, static call) * @param classname name of the class containing the method * (can be null - ignored, actually - if instance if provided, must be provided if static call) * @param amethodname name of the method to invoke * @param parameterTypes array of Classes * @param parameters array of Object * @return resulting Object * @throws CCException if any problem */ public static Object reflectionCall(final Object aninstance, final String classname, final String amethodname, final Class[] parameterTypes, final Object[] parameters) throws CCException { Object res;// = null; try { Class aclass;// = null; if(aninstance == null) { aclass = Class.forName(classname); } else { aclass = aninstance.getClass(); } //Class[] parameterTypes = new Class[]{String[].class}; final Method amethod = aclass.getDeclaredMethod(amethodname, parameterTypes); AccessController.doPrivileged(new PrivilegedAction() { public Object run() { amethod.setAccessible(true); return null; // nothing to return } }); res = amethod.invoke(aninstance, parameters); } catch (final ClassNotFoundException e) { throw new CCException.Error(PROBLEM_TO_ACCESS+classname+CLASS, e); } catch (final SecurityException e) { throw new CCException.Error(PROBLEM_TO_ACCESS+classname+GenericConstants.HASH_DIESE+ amethodname + METHOD_SECURITY_ISSUE, e); } catch (final NoSuchMethodException e) { throw new CCException.Error(PROBLEM_TO_ACCESS+classname+GenericConstants.HASH_DIESE+ amethodname + METHOD_NOT_FOUND, e); } catch (final IllegalArgumentException e) { throw new CCException.Error(PROBLEM_TO_ACCESS+classname+GenericConstants.HASH_DIESE+ amethodname + METHOD_ILLEGAL_ARGUMENTS+String.valueOf(parameters)+GenericConstants.CLOSING_ROUND_BRACKET, e); } catch (final IllegalAccessException e) { throw new CCException.Error(PROBLEM_TO_ACCESS+classname+GenericConstants.HASH_DIESE+ amethodname + METHOD_ACCESS_RESTRICTION, e); } catch (final InvocationTargetException e) { throw new CCException.Error(PROBLEM_TO_ACCESS+classname+GenericConstants.HASH_DIESE+ amethodname + METHOD_INVOCATION_ISSUE, e); } return res; }
Object obj; Method method = obj.getClass().getMethod("methodName", null); method.invoke(obj, null);
//Step1 - Using string funClass to convert to class String funClass = "package.myclass"; Class c = Class.forName(funClass); //Step2 - instantiate an object of the class abov Object o = c.newInstance(); //Prepare array of the arguments that your function accepts, lets say only one string here Class[] paramTypes = new Class[1]; paramTypes[0]=String.class; String methodName = "mymethod"; //Instantiate an object of type method that returns you method name Method m = c.getDeclaredMethod(methodName, paramTypes); //invoke method with actual params m.invoke(o, "testparam");
如果多次执行调用,则可以使用Java 7中引入的新方法句柄.这里我们将返回一个返回String的方法:
Object obj = new Point( 100, 200 ); String methodName = "toString"; ClassresultType = String.class; MethodType mt = MethodType.methodType( resultType ); MethodHandle methodHandle = MethodHandles.lookup().findVirtual( obj.getClass(), methodName, mt ); String result = resultType.cast( methodHandle.invoke( obj ) ); System.out.println( result ); // java.awt.Point[x=100,y=200]
这听起来像Java Reflection包可以使用的东西.
http://java.sun.com/developer/technicalArticles/ALT/Reflection/index.html
特别是在名称调用方法下:
import java.lang.reflect.*;
public class method2 { public int add(int a, int b) { return a + b; } public static void main(String args[]) { try { Class cls = Class.forName("method2"); Class partypes[] = new Class[2]; partypes[0] = Integer.TYPE; partypes[1] = Integer.TYPE; Method meth = cls.getMethod( "add", partypes); method2 methobj = new method2(); Object arglist[] = new Object[2]; arglist[0] = new Integer(37); arglist[1] = new Integer(47); Object retobj = meth.invoke(methobj, arglist); Integer retval = (Integer)retobj; System.out.println(retval.intValue()); } catch (Throwable e) { System.err.println(e); } } }
请参考以下代码可能对您有所帮助.
public static Method method[]; public static MethodClass obj; public static String testMethod="A"; public static void main(String args[]) { obj=new MethodClass(); method=obj.getClass().getMethods(); try { for(int i=0;i谢谢....
12> Marcel..:我这样做是这样的:
try { YourClass yourClass = new YourClass(); Method method = YourClass.class.getMethod("yourMethodName", ParameterOfThisMethod.class); method.invoke(yourClass, parameter); } catch (Exception e) { e.printStackTrace(); }
13> 小智..:Method method = someVariable.class.getMethod(SomeClass); String status = (String) method.invoke(method);
SomeClass
是类,someVariable
是变量。