2015-09-09 16 views
0

Я пытаюсь определить карту fieldName-> Method, которую я могу повторно использовать для нескольких экземпляров. Идея состоит в том, что я буду использовать отражение только один раз, а не для каждого экземпляра.Отражение вложенных вызовов метода

Например, при заданном ниже классе Клиента карта будет иметь имя, указывающее на объект Method, который соответствует имени getName() - Map < «name», Class.getName()>. Затем я могу вызвать метод getName() для любого экземпляра класса Client.

Как мне обрабатывать вложенные свойства. Например, учитывая приведенный ниже класс Currency, как мне получить объект Method, который будет вызывать Client.accounts [1] .currency.code?

public class Client{ 

    @Field(value = "name") 
    public String getName(){...} 

    @Field(value = "accounts") 
    public List<Account> getAccounts(){...} 
} 

public class Account{ 

    @Field(value = "acctNum") 
    public Long getAcctNum(){...} 

    @Field(value = "currency") 
    public Currency getCurrency(){...} 
} 

public class Currency{ 
    @Field(value = "code") 
    public String getCode(){...} 
} 

Сначала я создаю карту fieldName to Method. Что-то, что я планирую делать только один раз, а затем повторно использовать для экземпляров объектов.

Map<String, Method> fieldMap = new HashMap(); 
for(Method method : Client.class.getDeclaredMethods()){ 
    Annotation annotation = method.getAnnotation(com.acme.Field.class); 
    if(annotation == null) { 
     continue; 
    } 

    com.acme.Field fieldMapping = (com.acme.mapping.Field) annotation; 
    String fieldName = fieldMapping.value(); 
    fieldMap.put(fieldName, method); 
} 

Вот как я планирую использовать его

Client client = new Client(); 
for(Map.Entry<String, Method> entry : fieldMap.entrySet()){ 
    System.out.println(entry.getKey()+" -> "+entry.getValue().invoke(client, null)); 
} 
+0

Он смотрит на меня как вложенную Доступ собственности в Apache BeanUtils: HTTP: // StackOverflow .com/questions/2753218/how-to-prevent-npe-when-access-a-nested-indexed-property-of-a-bean – rsutormin

+0

И он также работает для элементов в списках. Взгляните на «2.3 Вложенный доступ к ресурсам» здесь: https://commons.apache.org/proper/commons-beanutils/javadocs/v1.8.3/apidocs/org/apache/commons/beanutils/package-summary.html# standard.nested – rsutormin

ответ

0

Для этих целей апача утилитами фасоли очень полезно. Потому что это одна из самых популярных java-библиотек.

Но для небольших проектов я использую самостоятельно написал утилиту https://bitbucket.org/cache-kz/reflect4j/overview

Он поддерживает POJO стиль объектов, с общественными полями. Ex:

public class A { 
    public int a; 
    public int b; 
} 

Или Java Bean стиль объектов, с добытчиками и сеттеров. Ex:

public class A { 
    protected int a; 
    protected int b; 

    public int getA() { 
    return a; 
    } 
    public void setA(int a) { 
    this.a = a; 
    } 
    public int getB(){ ... } 
    public void setB(int b) { ... } 
} 

Смешанные объекты поддерживаются тоже.

Для примера код будет просто:

import kz.cache.reflect4j.ObjectManager 
ObjectManager manag = new ObjectManager(); 
Object currencyCode = reader.getValue("accounts[1].currency.code", instanceOfClient); 

другие примеры можно найти в тестовом пакете: https://bitbucket.org/cache-kz/reflect4j/src/c344d76a4896235f6a1b09b2499d5ae25adc2900/src/test/java/kz/cache/reflect4j/ObjectManagerTest.java

Смежные вопросы