我的班级结构如下
ClassA{}
ClassB extends ClassA{}
ClassC extends ClassB{}
这些类包含一个字段name
,我不知道该字段存在于哪个类中,我有一个string name
和ClassC
的对象。我正在使用反射来获取我的代码
private static Field getType(Object obj,String fieldName){
Field type = null;
try
{
type = obj.getClass().getDeclaredField(fieldName);
}
catch (NoSuchFieldException e) {
try
{
type = obj.getClass().getSuperclass().getDeclaredField(fieldName);
}
catch (NoSuchFieldException e1) {
e.printStackTrace();
}
} catch (SecurityException e) {
e.printStackTrace();
}
return type;
}
但它只检查当前类及其超类中的字段,如果我想检查字段直到顶级类,我需要继续写try catch块。我认为这不是正确的方法。有没有替代解决方案呢? 提前致谢
答案 0 :(得分:4)
我认为您正在尝试做类似的事情:
Class cls = obj.getClass();
for (Class acls = cls; acls != null; acls = acls.getSuperclass()) {
try {
Field field = acls.getDeclaredField(fieldName);
// if not found exception thrown
// else return field
return field;
} catch (NoSuchFieldException ex) {
// ignore
}
}
答案 1 :(得分:2)
使用getField
代替getDeclaredField
。如果在给定的类中没有立即找到接口和父类中的字段,它将在接口和父类中查找字段。
答案 2 :(得分:2)
将try块包装到循环中怎么样:
Field type = null;
Class clz = object.getClass();
while(clz != null || clz != Object.class) {
try
{
type = clz.getDeclaredField(fieldName);
break;
} catch (NoSuchFieldException e) {
clz = object.getSuperclass();
}
}
return type;
答案 3 :(得分:0)
你可以使用while(或任何其他类似的)循环来保持扫描,直到找到匹配为止。
private static Field getType(Object obj,String fieldName){
Field type = null;
Class clazz = obj.getClass();
while (type==null && clazz!=null) {
try {
type = obj.getClass().getDeclaredField(fieldName);
} catch (NoSuchFieldException e) {
clazz = clazz.getSuperClass();
} catch (SecurityException e) {
e.printStackTrace();
return null;
}
return type;
}
最好检查字段是否存在而不是使用异常来控制流程,但这样可行。
答案 4 :(得分:0)
试试这个,它将处理超类和嵌套属性。
public static boolean isFieldExist(Class<?> clazz, String property) {
String[] fields = property.split("\\.");
try {
Field file = clazz.getDeclaredField(fields[0]);
if (fields.length > 1) {
return isFieldExist(file.getType(), property.substring(property.indexOf('.') + 1, property.length()));
}
return true;
} catch (NoSuchFieldException | SecurityException e) {
if (clazz.getSuperclass() != null) {
return isFieldExist(clazz.getSuperclass(), property);
}
return false;
}
}