Как использовать список параметризованных имен и типов свойств для Java-бина - PullRequest
0 голосов
/ 12 апреля 2011

Скажи, у меня есть боб

public class SomeBean{
     List<String> messages;
     List<Integer> scores;
     String id;
     int  number;

.... }

Я использую следующий код для обработки или сброса свойств

        BeanInfo beanInfo = Introspector.getBeanInfo(beanClass, Object.class);
        PropertyDescriptor descriptors[] = beanInfo.getPropertyDescriptors();
        int stop = descriptors.length;
        for (int i = 0; i < stop; ++i) {
            PropertyDescriptor descriptor = descriptors[i];
            logger.info(descriptor.getName() + " : " + descriptor.getPropertyType().getName() + ", writemethod :" + descriptor.getWriteMethod());

        }

То, что я хочу иметь возможность получить параметризованный тип для «баллов» и «сообщений». Когда я испортил код, значение для "descriptor.getPropertyType (). GetName ()" равно "java.util.List" как для сообщений, так и для оценок.

Как мне узнать, относится ли дескриптор свойства для «сообщения» к List<String>, а для «оценки» относится к List<Integer>?

Ответы [ 2 ]

7 голосов
/ 12 апреля 2011

Существует два случая.

Первый случай, когда параметризованный тип свойства неизвестен во время компиляции:

public class Pair<A, B> {
  public A getFirst() { ... }
  public B getSecond() { ... }
}

В этом случае вы не можете знать во время компиляции,и это то, о чем говорит @darioo.

Второй случай - ваш, когда параметры типа свойств известны во время выполнения.Приведенный ниже код должен помочь вам точно определить, что вы хотите сделать:

BeanInfo beanInfo = Introspector.getBeanInfo(beanClass, Object.class);
PropertyDescriptor descriptors[] = beanInfo.getPropertyDescriptors();
for (PropertyDescriptor d : descriptors) {
    final Type type = d.getReadMethod().getGenericReturnType();
    if (type instanceof ParameterizedType) {
        ParameterizedType pt = (ParameterizedType) type;
        System.out.println(d.getDisplayName());
        for (Type atp : pt.getActualTypeArguments()) {
            System.out.println("  " + atp);
        }
    }
}

Ключ здесь заключается в том, чтобы получить метод чтения или записи и использовать API Method.getGenericReturnType() или Method.getParameterTypes() соответственно.

Обратите внимание, что работа с java.lang.reflect.Type в общем случае становится довольно утомительной / хитрой, рассмотрим, например:

public Map<Nation, Map<A extends PostCode, B extends Location>> getGlobalPostCodes() { ... }
0 голосов
/ 12 апреля 2011

Пока поля имеют полностью указанные типы времени компиляции, как в вашем примере (List<String>, а не что-то вроде List<T>, то есть), вы можете использовать отражение для получения этой информации:

for (Field field : SomeBean.class.getDeclaredFields()) {
  Type type = field.getGenericType();
  System.out.println(field.getName() + ": " + type);
  if (type instanceof ParameterizedType) {
    ParameterizedType parameterized = (ParameterizedType) type;
    Type raw = parameterized.getRawType(); // This would be Class<List>, say
    Type[] typeArgs = parameterized.getActualTypeArguments();
    System.out.println(Arrays.toString(typeArgs));
  }
}

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

...