14

如何检查给定类是否具有特定字段以及是否已初始化(目前具有值)?

abstract class Player extends GameCahracter {

}

public class Monster extends GameCahracter{

    public int level = 1;
}
abstract class GameCharacter{

   public void attack(GameCahracter opponent){

         if (opponent instanceof Monster && ){ // << here I have to know is it instance of Monster and if it has initialized value
           }
}
4

5 回答 5

13

要查看一个类是否具有不依赖异常的属性,可以使用以下方法:

private Boolean objectHasProperty(Object obj, String propertyName){
    List<Field> properties = getAllFields(obj);
    for(Field field : properties){
        if(field.getName().equalsIgnoreCase(propertyName)){
            return true;
        }
    }
    return false;
}

private static List<Field> getAllFields(Object obj){
    List<Field> fields = new ArrayList<Field>();
    getAllFieldsRecursive(fields, obj.getClass());
    return fields;
}

private static List<Field> getAllFieldsRecursive(List<Field> fields, Class<?> type) {
    for (Field field: type.getDeclaredFields()) {
        fields.add(field);
    }

    if (type.getSuperclass() != null) {
        fields = getAllFieldsRecursive(fields, type.getSuperclass());
    }

    return fields;
}

并简单地调用:

objectHasProperty(objInstance, "myPropertyName");

其实无所谓类的实例,看看类有没有属性,不过我是这么弄的,只是为了友好一点。总结一下:我使 getAllFields 是递归的,以获取所有超类方法(在我的情况下,这很重要)

之后,如果您想查看所需对象中属性的值是什么,您可以调用:

PropertyUtils.getProperty(objInstance, "myPropertyName");

记住:如果objInstance没有那个属性,上面的调用会抛出NoSuchMethodException(这就是为什么你需要使用第一个代码来查看这个类是否有这个属性)

于 2014-08-27T12:06:01.937 回答
7

您可以使用反射,例如:

Class.forName("Foo").getFields() 

然后您可以再次检查特定对象是否使用反射初始化了该字段。

于 2012-04-14T19:29:48.133 回答
4

您不必为此使用反射,只需使用 if 条件即可。

 if (opponent !=null && opponent instanceof Monster && ((Monster) opponent).level==1){ // << here I have to know is it instance of Monster and if it has initialized value
           }

如果实例不为空并且它是 Monster 的实例,则可以检查实例不为空,那么在您的情况下,它肯定已初始化。如果怪物的对手实例的级别为 1,则每当创建新实例时,实例变量都会使用默认值初始化。

于 2012-04-14T19:38:32.717 回答
0

除了@Renato Lochetti 的答案,我还想添加一个只有一个函数的变体,而不是使用 3:

private boolean hasField(final Class<?> clazz, final String fieldName) {
    // gather all fields of this class
    final List<Field> fields = new ArrayList<>();
    Class<?> current = clazz;
    do {
        Collections.addAll(fields, current.getDeclaredFields());
    } while ((current = clazz.getSuperclass()) != null);

    // check if field exists
    return fields.stream().map(Field::getName).anyMatch(f -> f.equals(fieldName));
}
于 2022-02-23T12:34:26.973 回答
-5
//Load the class 

Class clazz = Class.forName("your.class.ClassName");
Field field = clazz.getField("fieldName")
if(field!=null){
 //field exist now check if its initialized or not, or if its primitive field check against its assumed initialized value
 if(ClassName.fieldName!=null){
    //yes initilized
 }
}
于 2012-04-14T19:27:19.240 回答