Нет лингвистической поддержки, чтобы сделать то, о чем вы просите.
Вы можете рефлексивно обращаться к членам типа во время выполнения, используя отражение (например, с помощью Class.getDeclaredFields()
для получения массива Field
), но в зависимости от того, что вы пытаетесь сделать, это может быть не лучшим решением.
Смотрите также
Связанные вопросы
пример
Вот простой пример, показывающий лишь часть того, на что способно отражение.
import java.lang.reflect.*;
public class DumpFields {
public static void main(String[] args) {
inspect(String.class);
}
static <T> void inspect(Class<T> klazz) {
Field[] fields = klazz.getDeclaredFields();
System.out.printf("%d fields:%n", fields.length);
for (Field field : fields) {
System.out.printf("%s %s %s%n",
Modifier.toString(field.getModifiers()),
field.getType().getSimpleName(),
field.getName()
);
}
}
}
В приведенном выше фрагменте кода используется отражение для проверки всех объявленных полей class String
; он производит следующий вывод:
7 fields:
private final char[] value
private final int offset
private final int count
private int hash
private static final long serialVersionUID
private static final ObjectStreamField[] serialPersistentFields
public static final Comparator CASE_INSENSITIVE_ORDER
Эффективное Java 2-е издание, Правило 53: Предпочитайте интерфейсы отражению
Это отрывки из книги:
Для данного Class
объекта вы можете получить Constructor
, Method
и Field
экземпляры, представляющие конструкторы, методы и поля класса. [Они] позволяют вам рефлексивно манипулировать своими основными собратьями . Однако эта сила имеет свою цену:
- Вы теряете все преимущества проверки во время компиляции.
- Код, необходимый для выполнения рефлексивного доступа, громоздок и многословен.
- Страдает производительность.
Как правило, в обычных приложениях во время выполнения объекты не должны подвергаться рефлексивному доступу.
Есть несколько сложных приложений, требующих рефлексии. Примеры включают [... опущено намеренно ...] Если у вас есть какие-либо сомнения относительно того, попадает ли ваше приложение в одну из этих категорий, вероятно, нет.
Field.get
что вы можете использовать для рефлексивного чтения значений поля. Если это такprivate
, вы сможете обойти это с помощьюsetAccessible
. Да, отражение - это очень мощный инструмент, который позволяет вам делать такие вещи, как проверкаprivate
полей, перезаписьfinal
полей, вызовprivate
конструкторов и т. Д. Если вам нужна дополнительная помощь с аспектом дизайна, вам, вероятно, следует написать новый вопрос с гораздо большей информацией. Возможно, вам вообще не нужны эти многие атрибуты (например, использованиеenum
илиList
и т. Д.).static void inspect(Class<?> klazz)
Прямой доступ к полям - не очень хороший стиль в java. Я бы предложил создать методы получения и установки для полей вашего bean-компонента, а затем использовать классы Introspector и BeanInfo из пакета java.beans.
MyBean bean = new MyBean(); BeanInfo beanInfo = Introspector.getBeanInfo(MyBean.class); for (PropertyDescriptor propertyDesc : beanInfo.getPropertyDescriptors()) { String propertyName = propertyDesc.getName(); Object value = propertyDesc.getReadMethod().invoke(bean); }
источник
propertyDesc.getReadMethod().getDeclaringClass() != Object.class
, или вы можете указать класс для остановки анализа в качестве второго параметра, напримерgetBeanInfo(MyBean.class, Object.class)
.Хотя я согласен с ответом Йорна если ваш класс соответствует спецификации JavaBeabs, вот хорошая альтернатива, если это не так, и вы используете Spring.
Spring имеет класс ReflectionUtils, который предлагает очень мощную функциональность, включая doWithFields (класс, обратный вызов) , метод в стиле посетителя, который позволяет вам перебирать поля классов с помощью объекта обратного вызова, подобного этому:
public void analyze(Object obj){ ReflectionUtils.doWithFields(obj.getClass(), field -> { System.out.println("Field name: " + field.getName()); field.setAccessible(true); System.out.println("Field value: "+ field.get(obj)); }); }
Но вот предупреждение: класс помечен как «только для внутреннего использования», что жаль, если вы спросите меня.
источник
Простой способ перебрать поля класса и получить значения из объекта:
Class<?> c = obj.getClass(); Field[] fields = c.getDeclaredFields(); Map<String, Object> temp = new HashMap<String, Object>(); for( Field field : fields ){ try { temp.put(field.getName().toString(), field.get(obj)); } catch (IllegalArgumentException e1) { } catch (IllegalAccessException e1) { } }
источник
В Java есть Reflection (java.reflection. *), Но я бы посоветовал заглянуть в такую библиотеку, как Apache Beanutils, это сделает процесс намного менее сложным, чем использование отражения напрямую.
источник
Вот решение, которое сортирует свойства в алфавитном порядке и печатает их все вместе с их значениями:
public void logProperties() throws IllegalArgumentException, IllegalAccessException { Class<?> aClass = this.getClass(); Field[] declaredFields = aClass.getDeclaredFields(); Map<String, String> logEntries = new HashMap<>(); for (Field field : declaredFields) { field.setAccessible(true); Object[] arguments = new Object[]{ field.getName(), field.getType().getSimpleName(), String.valueOf(field.get(this)) }; String template = "- Property: {0} (Type: {1}, Value: {2})"; String logMessage = System.getProperty("line.separator") + MessageFormat.format(template, arguments); logEntries.put(field.getName(), logMessage); } SortedSet<String> sortedLog = new TreeSet<>(logEntries.keySet()); StringBuilder sb = new StringBuilder("Class properties:"); Iterator<String> it = sortedLog.iterator(); while (it.hasNext()) { String key = it.next(); sb.append(logEntries.get(key)); } System.out.println(sb.toString()); }
источник