看場

2011-09-06 55 views
16

存在我有各種變量看場

public class myClass{ 

    public int id; 
    public String category; 
    public String description; 
    public String start; 
    public String end; 
} 

有沒有一種方法來檢查,通過創建一個內部函數或調用對象檢查,變量是否存在一類?

E.g.檢查myClass是否包含一個名爲「category」的變量(它的確如此)。或者它是否包含一個名爲「foo」的類別(它沒有)。

回答

29

你的編譯器通常都知道,相當不錯,並且運行時,可以檢查加載的類與反思。

Object someObject = ... 
Class<?> someClass = someObject.getClass(); 
Field someField = someClass.getField("foo"); 

如果找不到字段,getField()方法會拋出異常。

+3

或者,如果它不能被訪問一個SecurityException(例如它的'private') – CrackerJack9

+0

完美,謝謝! – emachine

+2

@ CrackerJack9沒有,訪問與'getfield命令()'不會拋出'SecurityException'私人領域。 – Bombe

2

你可以使用reflection來做到這一點,雖然我會建議檢查它是否真的需要,或者有另一種方法可以做到。

例如:

Class<?> clz = MyClass.class; 
try { 
    Field f = clz.getField("foo") 
} 
catch (NoSuchFieldException ex) { 
    // field doesn't exist 
} 
catch (SecurityException ex) { 
    // no access to field 
} 
4

正如其他人已經提到的反映是你所需要的。

如果您需要訪問私有字段可以使用 Class.getDeclaredField(String name)

0

使用那種Reflections-

private Set<String> getAllFields(final Class<?> type) { 
     Set<String> fields = new HashSet<String>(); 
     for (Field field : type.getDeclaredFields()) { 
      fields.add(field.getName()); 
     } 

     if (type.getSuperclass() != null) { 
      fields.addAll(getAllFields(type.getSuperclass())); 
     } 
     return fields; 
    }  
    private boolean listHasProperty(final Set<String> properties, final String propertyName) { 
     if (properties.contains(propertyName)) { 
      return true; 
     } 
     return false; 
    } 

以下方法然後檢查屬性存在using-

Set<String> fieldSet = getAllFields(object.getClass()); 
boolean isPresent=listHasProperty(fieldSet , sourceProperty) 

欲瞭解更多詳情,請檢查此post

0

這樣做在單步驟中有點不方便。

當我們轉向多態概念時,存在一些挑戰,例如通過引用包含相同字段但包含靜態類型和最終類型的其他專用類(ABCXMLDOMnodes類,ABCHTMLDOMnodes類)動態地獲取數據的類(ABC類)生成缺少對象。希望你有這個要求。

1.創建字段的ArrayList這三個類的簡單名稱爲全局。

private static ArrayList<String> getAllFieldsSimpleNames(Class<?> beanClass) { 
    ArrayList<String> fieldNames = new ArrayList<String>(); 
    Field[] fields = beanClass.getDeclaredFields(); 
    for (Field field : fields) { 
     fieldNames.add(field.getName()); 
    } 
    return fieldNames; 
} 

2.And然後生成對象,我們驗證字段(比如> 10個字段)針對助手類像下面的每一次是容易我感覺。

for(String a :abcFieldNames){ 
     if(abcXMLfieldnames.contains(a)){ 
     //code here 
     }else if(abcHTMLfieldnames.contains(a){ 
     //code here 
     } 
    } 

其他簡單的和動態的方式創造

 HashMap<Class<?>, ArrayList<String>> = ... 
    hm.put(ABC.class, getAllFieldsSimpleNames(ABC.class)); 
    hm.put(ABCXMLDOMnodes.class, getAllFieldsSimpleNames(ABCXMLDOMnodes.class)); 
if(hm.get(ABCXMLDOMnodes.class).contains("a"){...} 

我的建議,Oracle公司JAVA網絡是如果「類的類」可以提供一種方法,返回給定類的字段名稱列表作爲字符串類型只會有所幫助。

12

警告:接受答案的工作,但它依賴於異常控制流,這是bad practice,應儘可能避免。

相反,考慮以下選擇:

public boolean doesObjectContainField(Object object, String fieldName) { 
    Class<?> objectClass = object.getClass(); 
    for (Field field : objectClass.getFields()) { 
     if (field.getName().equals(fieldName)) { 
      return true; 
     } 
    } 
    return false; 
} 

還是比較簡潔的形式使用Java 8流:

public boolean doesObjectContainField(Object object, String fieldName) { 
    return Arrays.stream(object.getClass().getFields()) 
      .anyMatch(f -> f.getName().equals(fieldName)); 
} 

這些代碼片斷不依賴於異常的控制流和實際上做根本不需要任何異常處理,這將使您的實現更簡單,更具可讀性。您只需調用的方法之一以上類似下面的一段代碼:

Object someObject = ... ; 
boolean fieldExists = doesObjectContainField(someObject, "foo"); 

作爲一個側面說明,如果你需要訪問類的私有字段(但不是父類字段),你可以簡單地通過getDeclaredFields更換呼叫getFields