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
字段。