按ID设置字段?

时间:2015-10-07 19:13:34

标签: java

我从网络接收对象。

我需要设置特定字段的值。但是,我希望每次都避免使用反射来查找字段。

理想情况下,我想做类似的事情:

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>

1 个答案:

答案 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