我有一个包含各种变量的类
public class myClass{
public int id;
public String category;
public String description;
public String start;
public String end;
}
有没有办法通过创建内部函数或检查调用对象来检查变量是否存在?
E.g。检查myClass是否包含一个名为“category”的变量(确实如此)。或者它是否包含一个名为“foo”的类别(它没有)。
答案 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网络的建议是,如果“类类”可以提供一种方法,该方法返回给定类的字段名称列表,只对字符串类型有帮助。