То, как циклично выполниться по Классу, приписывает в Java?

То, как я могу циклично выполниться по классу, приписывает в Java динамично.

Для, например:

public class MyClass{
    private type1 att1;
    private type2 att2;
    ...

    public void function(){
        for(var in MyClass.Attributes){
            System.out.println(var.class);
        }
    }
}

действительно ли это возможно в Java?

76
задан moffeltje 7 February 2019 в 08:34
поделиться

4 ответа

Нет лингвистической поддержки, чтобы сделать то, о чем вы просите.

Вы можете рефлексивно обращаться к членам типа во время выполнения, используя отражение (например, с помощью 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

Эффективное 2-е издание Java, пункт 53: предпочитать интерфейсы отражению

Это выдержки из книги:

Учитывая объект Class , вы можете получить ] Конструктор , Метод и Поле экземпляры, представляющие конструкторы, методы и поля класса. [Они] позволяют вам манипулировать своими базовыми аналогами рефлексивно . Однако эта сила имеет свою цену:

  • Вы теряете все преимущества проверки во время компиляции.
  • Код, необходимый для выполнения рефлексивного доступа, неуклюж и многословен.
  • Производительность страдает.

Как правило, в обычных приложениях во время выполнения объекты не должны подвергаться рефлексивному доступу.

Есть несколько сложных приложений, требующих отражения. Примеры включают [... опущено намеренно ...] Если у вас есть какие-либо сомнения относительно того, попадает ли ваше приложение в одну из этих категорий, вероятно, нет.

91
ответ дан 24 November 2019 в 11:14
поделиться

В Java есть отражение (java.reflection. *), Но я бы посоветовал заглянуть в такую ​​библиотеку, как Apache Beanutils, это сделает процесс намного менее сложным, чем использование отражения напрямую.

6
ответ дан 24 November 2019 в 11:14
поделиться

Прямой доступ к полям - это не очень хороший стиль в java. Я бы предложил создать методы getter и setter для полей вашего боба, а затем использовать классы 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);
}
42
ответ дан 24 November 2019 в 11:14
поделиться

Хотя я согласен с ответом Йорна , если ваш класс соответствует спецификации JavaBeabs, вот хорошая альтернатива, если это не так и вы используете Spring.

Spring имеет класс с именем ReflectionUtils , который предлагает некоторые очень мощные функции, включая doWithFields (class, callback) , метод в стиле посетителя, который позволяет вам перебирать поля классов, используя объект обратного вызова вроде этого:

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));

    });
}

Но вот предупреждение: класс помечен как «только для внутреннего использования», что очень жаль, если вы спросите меня

16
ответ дан 24 November 2019 в 11:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: