Получить список MethodHandle из ключевых полей, которые являются частными в объекте - PullRequest
1 голос
/ 13 марта 2019

У меня есть список объектов со многими частными полями, и я хотел бы сгруппировать их по нескольким ключевым полям, которые поступают из базы данных. Класс метода находится в другом пакете. Мой объект будет выглядеть как

public class MyObject {
private String field1;

private String field2;

private String field3;

private Integer field4;
...}

и ключевые поля могут быть любой комбинацией полей в Объекте

Я попытался получить список MethodHandle для ключевых полей. Этот список MethodHandle позже будет передан в поток и вызван для Collectors.groupingBy для формирования карты.

private static Map<List<String>, List<MyObject>>
        groupListBy(List<MyObject> objList, String[] keyFields) {

    final MethodHandles.Lookup lookup = MethodHandles.lookup();
    List<MethodHandle> handles = Arrays.stream(keyFields)
            .map(field -> {
                try {
                    // What I tried by didn't work
                    // Field f = objList.get(0).getClass().getDeclaredField(field);
                    // f.setAccessible(true);
                    return lookup.findGetter(MyObject.class, field, String.class);
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }).collect(Collectors.toList());
     .
     .
};

Однако при доступе к закрытому члену при формировании списка MethodHandle для закрытых полей в MyObject будет исключение незаконного доступа.

Могу ли я узнать, как я могу получить доступ к этим полям. Спасибо!

Редактировать: я знаю, что в Java 9 есть метод privateLookupIn (), но в настоящее время я использую Java 8.

1 Ответ

0 голосов
/ 13 марта 2019

Я просмотрел некоторые другие ответы и придумал это

    final MethodHandles.Lookup lookup = MethodHandles.lookup();
    Object obj = new Object();
    List<MethodHandle> handles = Arrays.stream(keyFields)
            .map(field -> {
                try {
                    PropertyDescriptor pd = new PropertyDescriptor(field, Object.class);
                    Method getter = pd.getReadMethod();
                    getter.setAccessible(true);
                    MethodHandle pmh = lookup.unreflect(getter);
                    return pmh;
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }).collect(Collectors.toList());
...