Java 从对象中私有的键字段获取MethodHandle列表

Java 从对象中私有的键字段获取MethodHandle列表,java,private-members,collectors,methodhandle,Java,Private Members,Collectors,Methodhandle,我有一个包含许多私有字段的对象列表,我想根据来自数据库的几个关键字段对它们进行分组。该方法类位于另一个包中。 我的物体看起来像 public class MyObject { private String field1; private String field2; private String field3; private Integer field4; ...} 关键字段可以是对象中字段的任意组合 我已尝试获取关键字段的MethodHandle列表。此MethodHandle列表稍

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

public class MyObject {
private String field1;

private String field2;

private String field3;

private Integer field4;
...}
关键字段可以是对象中字段的任意组合

我已尝试获取关键字段的MethodHandle列表。此MethodHandle列表稍后将被流式传输并为Collector.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());
     .
     .
};
私有静态映射
groupListBy(列表对象列表,字符串[]键域){
final MethodHandles.Lookup Lookup=MethodHandles.Lookup();
列表句柄=Arrays.stream(键域)
.map(字段->{
试一试{
//我试过的没用
//字段f=objList.get(0.getClass().getDeclaredField(字段);
//f.setAccessible(真);
返回lookup.findGetter(MyObject.class,field,String.class);
}捕获(例外e){
抛出新的运行时异常(e);
}
}).collect(Collectors.toList());
.
.
};
但是,当为MyObject中的私有字段形成MethodHandle列表时,访问私有成员会出现非法访问异常

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


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

我查看了一些其他答案,得出了这个结论

    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());
final MethodHandles.Lookup Lookup=MethodHandles.Lookup();
Object obj=新对象();
列表句柄=Arrays.stream(键域)
.map(字段->{
试一试{
PropertyDescriptor pd=新的PropertyDescriptor(字段,Object.class);
方法getter=pd.getReadMethod();
getter.setAccessible(true);
MethodHandle pmh=lookup.unreflect(getter);
返回pmh;
}捕获(例外e){
抛出新的运行时异常(e);
}
}).collect(Collectors.toList());

我浏览了一些其他答案,得出了这个答案

    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());
final MethodHandles.Lookup Lookup=MethodHandles.Lookup();
Object obj=新对象();
列表句柄=Arrays.stream(键域)
.map(字段->{
试一试{
PropertyDescriptor pd=新的PropertyDescriptor(字段,Object.class);
方法getter=pd.getReadMethod();
getter.setAccessible(true);
MethodHandle pmh=lookup.unreflect(getter);
返回pmh;
}捕获(例外e){
抛出新的运行时异常(e);
}
}).collect(Collectors.toList());

因为这是关于可访问性的,所以您应该提到特定代码位于哪个类/包中。显然,
groupListBy
方法不在
对象
类中,但不要让我们猜测。好吧,如果你不想惹麻烦的话,就不要给你的类命名
Object
。@Holger谢谢你,我已经改正了。哪个类正在调用
groupListBy
?是否可以让
MyObject
提供必要的查找对象?这将是最简单的解决方案,不需要访问覆盖(除了Java9解决方案)。显然,
groupListBy
方法不在
对象
类中,但不要让我们猜测。好吧,如果你不想惹麻烦的话,就不要给你的类命名
Object
。@Holger谢谢你,我已经改正了。哪个类正在调用
groupListBy
?是否可以让
MyObject
提供必要的查找对象?这将是最简单的解决方案,不需要访问覆盖(除了Java 9解决方案)。请注意,此方法的“getter”是一个
public…get…()
方法,与“getter”不同,它不需要访问覆盖由
MethodHandles.Lookup.findgeter
返回,它是访问
private
字段的句柄。请注意,使用此方法得到的“getter”是一个
public…get…()
方法,与“getter”不同,它不需要访问重写由
MethodHandles.Lookup.findGetter
返回,该句柄用于访问
private
字段。