我有以下代码,它允许我在扫描程序中输入我想要调用的Employee getter方法,它将使用反射(方法的名称不应出现在代码中的任何位置)。这适用于getter方法,但我现在需要修改代码以执行类似于setter方法的操作。过去一周我一直试图想办法,但我一直无法做到。任何帮助将不胜感激。
感谢。
public static void main(String[] args) {
Employee e = Employee.testEmployee(); // a sample employee
Class cls = e.getClass();
Scanner scanner = new Scanner (System.in); // to parse data the user types in
String nextCommand;
// until the user enters "quit", get the next input from the user, and if it matches
// a given command, get the desired information from the employee object
do {
System.out.print("Enter command >> ");
nextCommand = scanner.next();
Method method = null;
try{
method = cls.getMethod(nextCommand);
}
catch(NoSuchMethodException x) {
}
try{
System.out.println(method.invoke(e));
}
catch(IllegalAccessException x) {
}
catch(java.lang.reflect.InvocationTargetException x) {
}
catch(NullPointerException x) {
}
} while (! nextCommand.equals("quit"));
}
答案 0 :(得分:2)
这是一个代码示例,可以实现您想要实现的目标:
public class Test {
private static HashSet<Class<?>> classes = new HashSet<>();
static {
classes.add(String.class);
classes.add(Integer.class);
classes.add(GregorianCalendar.class);
}
public static void main(String[] args) throws NoSuchMethodException,
SecurityException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException {
X obj = new X();
obj.setField("lala");
Method method = obj.getClass().getMethod("getField", null);
System.out.println(method.invoke(obj, null));
Method setMethod = getWorkingMethod(obj);
setMethod.invoke(obj, "who let the dogs out");
System.out.println(obj.getField());
}
private static Method getWorkingMethod(Object obj) {
Method method = null;
for (Class<?> c : classes) {
try {
method = obj.getClass().getMethod("setField", c);
} catch (NoSuchMethodException | SecurityException e) {
continue;
}
if(method != null){
return method;
}
}
throw new IllegalArgumentException("No such method found!");
}
}
class X {
private String stringField;
public void setField(String s) {
stringField = s;
}
public String getField() {
return stringField;
}
}
输出:
拉拉
谁让狗出去
注意:
创建一个存储HashSet
个对象的集合(我使用Class<?>
)。您将使用这些来迭代各种可能性,并查看是否存在具有该参数的方法。
使用try-catch查看方法是否存在(当找不到它时会抛出异常)。
这不适用于重载方法。如果这是您的情况,您将不得不进行调整。我希望它没有问题,因为你说这是针对setter(通常没有重载)。
答案 1 :(得分:0)
您可以通过反射直接访问getter
来避免调用setter
和Field
方法。
Field对象有各种get
和set
方法,可用于操作字段值。
请参阅:http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#getField%28java.lang.String%29
示例强>
import java.lang.reflect.Field;
public class MyObject {
private String fieldA;
public String getFieldA() {
return fieldA;
}
public void setFieldA(String fieldA) {
this.fieldA = fieldA;
}
public static void main(String[] args) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
MyObject myObject = new MyObject();
myObject.setFieldA("Test");
Class clazz = myObject.getClass();
Field field = clazz.getDeclaredField("fieldA");
field.setAccessible(true);
String fieldA = (String) field.get(myObject);
System.out.println(fieldA);
field.set(myObject, "Test2");
fieldA = (String) field.get(myObject);
System.out.println(fieldA);
field.setAccessible(false); //be sure to return field to private
}
}
答案 2 :(得分:0)
java中的分辨率(方法或字段解析)会使执行时间减慢“10或100的订单”,因此不是智能设计决策。因此,在开始时解析一次缓存方法实例,并从缓存中执行它。避免使用反射进行频繁查找。