我从网络接收对象。
我需要设置特定字段的值。但是,我想避免每次都使用反射来查找字段。
理想情况下,我想做这样的事情:
int fieldNo = Something.getFieldID("numStairs",SomeClass.class); //do this only once
SomeClass s = (SomeClass)myObject;
s.setField(fieldNo,null);
基本上,首先,我查找我需要的字段的 id,然后我设置值,而不必每次都动态地执行反射来访问该字段。
我想知道在 Java 中是否可以实现类似的功能。
如果不是,给定一个 fieldName 字符串和一个对象(断言该字段确实存在)的有效方法是将该字段的值设置为 null(假设您还知道该字段可以为 null)。
最佳答案
下面是我的版本。
一些类
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
关于java - 通过id设置字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33000586/