Как проверить, имеет ли данный класс поле и он был инициализирован?
Как проверить, имеет ли данный класс определенное поле и если он инициализирован (имеет значение в данный момент)?
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
}
}
Ответы
Ответ 1
//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
}
}
Ответ 2
Вы можете использовать отражение, например, следующим образом:
Class.forName("Foo").getFields()
И затем вы можете снова проверить, если конкретный объект имеет это поле, инициализированное с помощью отражения.
Ответ 3
Вам не нужно использовать отражение для этого, вы можете просто сделать это с условием 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
}
Вы можете проверить, что экземпляр не является нулевым, если экземпляр не null и его экземпляр Monster, то в вашем случае его определенно инициализирован. Переменные экземпляра, инициализированные значениями по умолчанию, когда создается новый экземпляр, если экземпляр противника монстра, то уровень имеет значение 1.
Ответ 4
Чтобы узнать, обладает ли класс свойством без использования исключения, вы можете использовать следующие методы:
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
(Вот почему вам нужно использовать первый код, чтобы узнать, обладает ли класс свойством)