2012-01-31 118 views
2

我有一個類有幾個領域是另一個類的子類。我想在頂層類中快速找到該子類的所有實例。有沒有一個庫可以給我一個在另一個類中出現的類的所有實例?

例如

public class TopClass { 
private ClassIWant1 myVar1; 
private ClassIWant2 myVar2; 
private OtherJunk myVar3; 
private Nested myVar4; 
} 

public class Nested { 
private ClassIWant3 myVar11; 
} 

public class SuperClass { 
} 

public ClassIWant1 extends SuperClass {} 
public ClassIWant2 extends SuperClass {} 
public ClassIWant3 extends ClassIWant1 {} 

如果我是通過與TopClass一個實例我希望得到包含myVar1,myVar2和myVar11值的列表來運行例子。

我對如何使用反射來手動執行此操作的一般想法,但我希望我沒有推倒重來。有沒有可以做到這一點的圖書館?

我熟悉ReflectUtils,但我不知道如果能夠做到這一點或沒有。

+0

作爲參考,「快速」和「與反思」是......相互衝突的目標,除非你在的意義指的是「快」,「我不會寫太多的代碼。」 – 2012-01-31 23:30:21

+0

@LouisWasserman - 公平點。我的意思是後者。我已經決定使用反射,這是一種性能損失。如果存在通用庫,那麼我至少可以節省一些維護和測試時間,而不用編寫和測試我自己的代碼。 – Freiheit 2012-01-31 23:34:58

回答

1

如果我明白你的要求正確,你正在尋找的東西是這樣的:

public class Test { 
    public static void main(String[] args) { 
     TopClass top = …; // initialise as appropriate 
     System.out.println(findFields(top, SuperClass.class)); 
    } 

    private static <T> List<T> findFields(Object haystack, Class<T> needle) { 
     return findFields0(haystack, needle, new HashSet<Object>(), new ArrayList<T>()); 
    } 

    private static <T> List<T> findFields0(Object haystack, Class<T> needle, Set<Object> visited, List<T> result) { 
     if (visited.contains(haystack)) return result; // we already searched this object 

     visited.add(haystack); 

     for (Field field : haystack.getClass().getFields()) { 
      field.setAccessible(true); 
      Object fieldValue = null; 
      try { 
       fieldValue = field.get(haystack); 
      } catch (IllegalAccessException e) { 
       // shouldn't happen 
       throw new RuntimeException(e); 
      } 
      if (needle.isAssignableFrom(field.getType())) { 
       result.add(needle.cast(fieldValue)); 
      } 

      // recurse 
      findFields0(fieldValue, needle, visited, result); 
     } 
     return result; 
    } 
} 

這是通過使用靜態類型的字段作爲聲明。也就是說,如果您聲明一個字段爲Object,但它包含SuperClass或其後代之一的實例,則不會找到該實例。如果字段將它們設置爲值,它也將返回null。我不知道這會對原始類型做什麼。

免責聲明:代碼在一個樂觀的例子中進行了簡短的測試,如果它導致您的計算機着火,我不承擔任何責任。

+0

我認爲這是有效的,但我不得不稍微按摩一下,才能與裝有SuperClass實例的列表很好地玩。 – Freiheit 2012-02-01 15:57:01

+1

這很好。謝謝!我不得不添加一個else case以確定字段類型是否是ParameterizedType,然後獲取實際類型,然後如果其中一個類型可從needle分配,則將fieldValue中的所有元素添加到結果中。 – Freiheit 2012-02-01 16:38:21

-1

this method你在找什麼?

+0

是遞歸嗎?我認爲這給了我類的名字,但沒有給出一個實例的字段的值。 – Freiheit 2012-01-31 23:32:06

+0

我不認爲它是遞歸的,但我不認爲編寫一個遞歸調用這個方法會很困難。 – Dawood 2012-01-31 23:33:48

+0

-1:1)對於在網站上實際存在的問題的答案,而不是在用戶的想象中,這是可取的。 2)該方法似乎與OP要求的內容沒有關係。它將返回在類範圍內聲明的內部類,而不是其字段的值。 – millimoose 2012-02-01 00:29:27

相關問題