我从网络接收对象。
我需要设置特定字段的值。但是,我希望每次都避免使用反射来查找字段。
理想情况下,我想做类似的事情:
int fieldNo = Something.getFieldID("numStairs",SomeClass.class); //do this only once
SomeClass s = (SomeClass)myObject;
s.setField(fieldNo,null);
基本上,首先,我查找我需要的字段的id,然后设置值,而不必每次动态执行反射来访问字段。
我想知道在Java中是否可以使用这样的东西。
如果没有,给定一个fieldName字符串和一个Object(断言该字段确实存在)可能是一种有效的方法,将该字段的值设置为null(假设您也知道该字段可以为空)。 / p>
答案 0 :(得分:1)
我的版本如下。
SomeClass的
public class SomeClass {
private Integer numStairs;
public SomeClass(Integer numStairs) {
this.numStairs = numStairs;
}
public Integer getNumStairs() {
return numStairs;
}
}
主要
public class Main {
private static final Map<Class, Field> cache = new HashMap<>();
public static void main(String[] args) {
SomeClass x = new SomeClass(12345);
//Testing speed
System.out.println("Test 1");
int repeats = 10000000;
long count = 0;
long t1 = System.currentTimeMillis();
for (int i = 0; i < repeats; i++) {
setField(x, i);
if (x.getNumStairs() == i) {
count++;
}
}
long t2 = System.currentTimeMillis();
System.out.println("\tCount = " + count);
System.out.println("\tTime = " + (t2 - t1));
System.out.println("Test 2");
count = 0;
t1 = System.currentTimeMillis();
for (int i = 0; i < repeats; i++) {
setField2(x, i);
if (x.getNumStairs() == i) {
count++;
}
}
t2 = System.currentTimeMillis();
System.out.println("\tCount = " + count);
System.out.println("\tTime = " + (t2 - t1));
}
public static void setField(Object o, Integer value) {
try {
Field f = o.getClass().getDeclaredField("numStairs");
f.setAccessible(true);
f.set(o, value);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void setField2(Object o, Integer value) {
try {
Field f = cache.get(o.getClass());
if (f == null) {
f = o.getClass().getDeclaredField("numStairs");
f.setAccessible(true);
cache.put(o.getClass(), f);
}
f.set(o, value);
} catch (Exception e) {
e.printStackTrace();
}
}
}
输出:
Test 1
Count = 10000000
Time = 4092
Test 2
Count = 10000000
Time = 1003