查看类中是否存在字段

时间:2011-09-06 19:20:00

标签: java

我有一个包含各种变量的类

public class myClass{

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

有没有办法通过创建内部函数或检查调用对象来检查变量是否存在?

E.g。检查myClass是否包含一个名为“category”的变量(确实如此)。或者它是否包含一个名为“foo”的类别(它没有)。

6 个答案:

答案 0 :(得分:32)

你的编译器通常很清楚,运行时允许你用反射检查加载的类。

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

如果找不到该字段,getField()方法将抛出异常。

答案 1 :(得分:25)

警告:接受的答案可行,但它依赖例外作为控制流,即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");

作为旁注,如果您需要访问班级的私人字段(但不是父班级字段),则只需将getFields的调用替换为getDeclaredFields

答案 2 :(得分:6)

正如其他人已经提到的,反射就是你所需要的。

如果您需要访问私人字段,则可以使用 Class.getDeclaredField(String name)

答案 3 :(得分: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 :(得分:0)

您正在寻找的是“反思”。它在运行时提供了确定类中包含哪些字段和方法的能力。

http://today.java.net/pub/a/today/2008/02/12/reflection-in-action.html

答案 5 :(得分:0)

这样做有点不方便。

当我们转向多态概念时,存在一些挑战,例如通过引用包含相同字段但静态和最终类型的其他专用类(ABCXMLDOMnodes类,ABCHTMLDOMnodes类)来动态获取数据的类(ABC类)生成缺少对象。希望你有这个要求。

1.Creating ArrayList of fields这三个类的简单名称为全局。

 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.然后,每次生成一个对象时,我们都会对下面的助手类验证字段(比如说> 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 Corp. JAVA网络的建议是,如果“类类”可以提供一种方法,该方法返回给定类的字段名称列表,只对字符串类型有帮助。