1

我有一个包含许多私有字段的对象列表,我想根据来自数据库的几个关键字段对它们进行分组。方法类在另一个包中。我的对象看起来像

public class MyObject {
private String field1;

private String field2;

private String field3;

private Integer field4;
...}

关键字段可以是对象中字段的任意组合

我试图获取关键字段的 MethodHandle 列表。这个 MethodHandle 列表稍后将被流式传输并为 Collectors.groupingBy 调用以形成一个 Map。

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());
     .
     .
};

但是,在为 MyObject 中的私有字段形成 MethodHandle 列表时,访问私有成员将出现非法访问异常。

我可以知道如何访问这些字段。谢谢!

编辑:我知道 Java 9 中有一个名为 privateLookupIn() 的方法,但我目前使用的是 Java 8。

4

1 回答 1

0

我浏览了其他一些答案并想出了这个

    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());
于 2019-03-13T08:10:28.363 回答