如何检查给定的类是否有一个字段并且它已被初始化?

J.O*_*sen 12 java oop

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

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
           }
}
Run Code Online (Sandbox Code Playgroud)

Ren*_*tti 8

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

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;
}
Run Code Online (Sandbox Code Playgroud)

只需致电:

objectHasProperty(objInstance, "myPropertyName");
Run Code Online (Sandbox Code Playgroud)

事实上,类的实例并不重要,看看类是否有属性,但是我这样做了,只是为了更加友好.只是得出结论:我使getAllFields是递归的,以获得所有的超类方法(在我的情况下,这很重要)

之后,如果要查看所需对象中属性的值,可以调用:

PropertyUtils.getProperty(objInstance, "myPropertyName");
Run Code Online (Sandbox Code Playgroud)

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


hgr*_*rey 7

您可以使用反射,例如:

Class.forName("Foo").getFields() 
Run Code Online (Sandbox Code Playgroud)

然后,您可以再次检查特定对象是否已使用反射初始化此字段.


She*_*zad 5

您不必为此使用反射,只需使用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
           }
Run Code Online (Sandbox Code Playgroud)

如果instance不为空,并且实例为Monster的实例,则可以检查实例是否为null,然后根据您的情况将其明确初始化。每当创建新实例时,如果怪物的对手实例的等级为1时,实例变量将使用默认值初始化。


Jig*_*shi -6

//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
 }
}
Run Code Online (Sandbox Code Playgroud)

  • 实际上 [`Class.getField()`](http://docs.oracle.com/javase/6/docs/api/java/lang/Class.html#getField%28java.lang.String%29) 会抛出`NoSuchFieldException` 如果未找到该字段(它不会返回 null)并且依赖异常进行检查不是一个好主意 (16认同)
  • 正如@AhmadY.Saleh 所提到的,答案是无效的。getField() 不会返回 null,但会引发异常。 (2认同)