简体   繁体   中英

Get List of MethodHandle from key fields which are private in an object

I have a list of object with many private fields and I would want to group them according to a few key fields that come from a database. The method class is in another package. My object would look like

public class MyObject {
private String field1;

private String field2;

private String field3;

private Integer field4;
...}

and the key fields could be any combination of the fields in the Object

I have tried to get a list of MethodHandle for key fields. This list of MethodHandle would be later streamed and invoked for Collectors.groupingBy to form a 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());
     .
     .
};

However, there would be an Illegal Access Exception for accessing a private member when forming a list of MethodHandle for the private fields in the MyObject.

May I know how can I access those fields. Thank you!

Edit: I know there is a method called privateLookupIn() in Java 9, but I'm using Java 8 currently.

I looked through some other answers and came up with this

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM