2015-10-07 62 views
3

我從網絡接收對象。通過ID設置一個字段?

我需要設置特定字段的值。但是,我想避免每次都使用反射來查找該字段。

理想情況下,我希望做這樣的事情:

int fieldNo = Something.getFieldID("numStairs",SomeClass.class); //do this only once 
SomeClass s = (SomeClass)myObject; 
s.setField(fieldNo,null); 

基本上,第一,我仰望我需要的字段的ID的,然後我設置的值,而無需進行動態反射來訪問每次都是場。

我想知道在Java中是否可以這樣做。

如果沒有,給定fieldName String和Object(聲明該字段確實存在)的有效方法是什麼,以便將該字段的值設置爲null(假定您知道該字段爲空)。

+2

這是關於使用反射困擾你嗎?這真是這項工作的工具。 – RealSkeptic

+1

爲什麼不只是定義兩個幫助器方法來獲取和設置一個字段,隱藏反射代碼?只要做任何你想做的事情就可以做一個輔助函數。 –

+0

@RealSkeptic我真的對反射的表現持懷疑態度。我需要這個快點。 – jmasterx

回答

1

我的版本在下面。

SomeClass的

主要

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