Как прочитать атрибут объекта динамически в Java? - PullRequest
10 голосов
/ 13 октября 2011

Есть ли способ динамического чтения и печати атрибута объекта (Java)? например, если у меня есть следующий объект

public class A{
  int age ;
  String name;
  float income;

}

public class B{
 int age;
 String name;
}

public class mainA{
   A obj1 = new A();
   method(A);
   method(B); 
}

the output should be like

While running method(A):
Attribute of Object are age,name,income;
While executing method(B):
Attribute of Objects are age,name;

У меня вопрос: я могу передать различные объекты в метод (), есть ли способ получить доступ к атрибуту другого объекта в целом.

Ответы [ 5 ]

15 голосов
/ 13 октября 2011

Вы хотите использовать Reflection API . В частности, взгляните на обнаружение учеников .

Вы можете сделать что-то вроде следующего:

public void showFields(Object o) {
   Class<?> clazz = o.getClass();

   for(Field field : clazz.getDeclaredFields()) {
       //you can also use .toGenericString() instead of .getName(). This will
       //give you the type information as well.

       System.out.println(field.getName());
   }
}

Я просто хотел добавить предостережение, что вам обычно не нужно делать ничего подобного, и для большинства вещей вы, вероятно, не должны . Отражение может затруднить поддержку и чтение кода. Конечно, есть конкретные случаи, когда вы хотели бы использовать Reflection, но они относительно редки.

3 голосов
/ 17 февраля 2017

Используя org.apache.commons.beanutils.PropertyUtils, мы можем сделать это. Если для компонента определены правильные методы получения и установки, мы также можем динамически установить значение:

import org.apache.commons.beanutils.PropertyUtils;
import java.beans.PropertyDescriptor;

public class PropertyDescriptorTest {

    public static void main(String[] args) {

        // Declaring and setting values on the object
        AnyObject anObject = new AnyObject();
        anObject.setIntProperty(1);
        anObject.setLongProperty(234L);
        anObject.setStrProperty("string value");

        // Getting the PropertyDescriptors for the object
        PropertyDescriptor[] objDescriptors = PropertyUtils.getPropertyDescriptors(anObject);

        // Iterating through each of the PropertyDescriptors
        for (PropertyDescriptor objDescriptor : objDescriptors) {
            try {
                String propertyName = objDescriptor.getName();
                Object propType = PropertyUtils.getPropertyType(anObject, propertyName);
                Object propValue = PropertyUtils.getProperty(anObject, propertyName);

                // Printing the details
                System.out.println("Property="+propertyName+", Type="+propType+", Value="+propValue);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }

}

Чтобы установить значение определенного свойства:

// Here we have to make sure the value is
// of the same type as propertyName
PropertyUtils.setProperty(anObject, propertyName, value);

Вывод будет:

Property=class, Type=class java.lang.Class, Value=class genericTester.AnyObject
Property=intProperty, Type=int, Value=1
Property=longProperty, Type=class java.lang.Long, Value=234
Property=strProperty, Type=class java.lang.String, Value=string value
2 голосов
/ 13 октября 2011

Вы можете использовать отражение, чтобы получить каждое поле от вашего объекта (если конфигурация безопасности позволяет вам).

Если вам это нужно не для самообразования, то, возможно, стоит использовать ReflectionUtils от Apache Commons.

1 голос
/ 13 октября 2011

Вы можете использовать отражение, но API не очень хорошо использовать.Но то, что вы пытаетесь сделать, совсем не объектно-ориентировано.У A и B должен быть метод «напиши сам», который будет выводить их значения (необходимо указать метод в суперклассе / интерфейсе для вызова метода с использованием полиморфизма).

0 голосов
/ 13 октября 2011

Думаю, я бы подумал о другом подходе.

Если вы действительно хотите относиться к этим данным, есть ли причина, по которой они не могут быть хеш-таблицами (у них есть связанный код)?

Reflection сделает это, но это последнее средство - вы всегда должны серьезно рассмотреть различные подходы, прежде чем переходить к отражению.

Случаи, когда вам необходимо получить доступ к таким переменным, как, например, отображение базы данных (Hibernate) и внедрение (Весна).Возможно, вы захотите подумать, подходит ли вам подобное упакованное решение, чтобы будущие программисты могли понять, что вы сделали, не изучая все о вашем конкретном решении.

Кроме того, Spring инъекция может делать то, что может соответствовать вашим потребностям.

Также, если вы собираетесь использовать рефлексию, серьезно рассмотрите аннотации, чтобы не связывать свою функциональность с простыми произвольными именами атрибутов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...