Java 如何获取嵌套属性的方法?
我有一个Foo类,它是类型为Bar的属性Java 如何获取嵌套属性的方法?,java,reflection,javabeans,Java,Reflection,Javabeans,我有一个Foo类,它是类型为Bar的属性 public class Foo { public Bar getBar() { } } public class Bar { public String getName(); } 是否有一个助手类或方法可以使用Foo.class和“Bar.name”获得java.lang.reflect.method的name属性的对象 Commons BeanUtils中有一个名为PropertyUtils的类,但它的getProper
public class Foo {
public Bar getBar() {
}
}
public class Bar {
public String getName();
}
是否有一个助手类或方法可以使用Foo.class
和“Bar.name”获得java.lang.reflect.method
的name属性的对象
Commons BeanUtils中有一个名为PropertyUtils
的类,但它的getPropertyDescriptor()
仅适用于对象
实例,而不适用于类
实例
我意识到实现一个一点都不难,但我想利用已有的功能
另外,我需要一个Method对象这一事实并不是糟糕设计的结果(希望不是)。我正在做的是一个JavaBeans编辑器
谢谢 在Commons BeanUtils中,PropertyUtils.getPropertyDescriptors()
将类
作为输入,并返回PropertyDescriptor
的数组
我不知道它是否会返回“嵌套”名称,例如bar.name
,但如果不是,则在结果上递归并构建自己的嵌套名称列表应该不会太难
只是一个快速的精神检查。。。世界真的需要另一个JavaBeans编辑器吗?我选择MVEL或OGNL,跳过“我需要方法对象”的要求。这里是嵌套支持:
根据用例的不同,可以缓存检索到的类。例如,在使用重筛选的datatable crud应用程序中
/**
* Retrieves the type of the property with the given name of the given
* Class.<br>
* Supports nested properties following bean naming convention.
*
* "foo.bar.name"
*
* @see PropertyUtils#getPropertyDescriptors(Class)
*
* @param clazz
* @param propertyName
*
* @return Null if no property exists.
*/
public static Class<?> getPropertyType(Class<?> clazz, String propertyName)
{
if (clazz == null)
throw new IllegalArgumentException("Clazz must not be null.");
if (propertyName == null)
throw new IllegalArgumentException("PropertyName must not be null.");
final String[] path = propertyName.split("\\.");
for (int i = 0; i < path.length; i++)
{
propertyName = path[i];
final PropertyDescriptor[] propDescs = PropertyUtils.getPropertyDescriptors(clazz);
for (final PropertyDescriptor propDesc : propDescs)
if (propDesc.getName().equals(propertyName))
{
clazz = propDesc.getPropertyType();
if (i == path.length - 1)
return clazz;
}
}
return null;
}
/**
*检索具有给定属性的给定名称的属性类型
*类。
*支持遵循bean命名约定的嵌套属性。
*
*“foo.bar.name”
*
*@see PropertyUtils#getPropertyDescriptors(类)
*
*@param-clazz
*@param propertyName
*
*@如果不存在属性,则返回Null。
*/
公共静态类getPropertyType(类clazz,字符串propertyName)
{
if(clazz==null)
抛出新的IllegalArgumentException(“Clazz不能为null”);
如果(propertyName==null)
抛出新的IllegalArgumentException(“PropertyName不能为null”);
最终字符串[]路径=propertyName.split(“\\”);
for(int i=0;i
这是一个来自的版本,如果有人感兴趣,Java 8 streams返回可选
/**
* Retrieves the type of the property with the given name of the given Class.
*
* Supports nested properties following bean naming convention "foo.bar.name"
*
* @return Optional.empty if no property exists.
* @see PropertyUtils#getPropertyDescriptors(Class)
*/
public static Optional<Class<?>> findPropertyType(@NotNull Class<?> clazz, @NotBlank String propertyName) {
return Arrays.stream(propertyName.split("\\.")).reduce(
Optional.ofNullable(clazz), // identity -> initial value of the accumulator
(Optional<Class<?>> accOptClazz, String nextPropertyName) -> // accumulator with current value and next value from string
stream(accOptClazz)
.map((Class<?> accClazz) -> Arrays.stream(PropertyUtils.getPropertyDescriptors(accClazz)))
.flatMap(Function.identity())
.filter(propDesc -> propDesc.getName().equals(nextPropertyName))
.findFirst().map(PropertyDescriptor::getPropertyType),
(clazzA, clazzB) -> null // needed but useless combiner (only for parallel reduce)
);
}
/**
* Turns an Optional<T> into a Stream<T> of length zero or one depending upon whether a value is present.
*/
public static <T> Stream<T> stream(Optional<T> opt) {
return opt.isPresent() ? Stream.of(opt.get()) : Stream.empty();
}
/**
*检索具有给定类的给定名称的属性类型。
*
*支持遵循bean命名约定“foo.bar.name”的嵌套属性
*
*@return可选。如果不存在属性,则为空。
*@see PropertyUtils#getPropertyDescriptors(类)
*/
publicstaticoptional是通过尝试将Spring数据排序转换为Comparator得到的
public class ComparatorUtils {
public static <T> Comparator<T> fromSort(Sort sort, Class<T> type) {
final Iterator<Sort.Order> orderIterator = sort.iterator();
final Sort.Order order = orderIterator.next();
Comparator<T> comparator = fromSortOrder(order, type);
while (orderIterator.hasNext()) {
comparator = comparator.thenComparing(fromSortOrder(orderIterator.next(), type));
}
return comparator;
}
private static <T> Comparator<T> fromSortOrder(Sort.Order order, Class<T> type) {
final List<Method> accessMethods = new ArrayList<>();
Class<?> currentClass = type;
for (String property : order.getProperty().split("\\.")) {
Method m = Objects.requireNonNull(BeanUtils.getPropertyDescriptor(currentClass, property)).getReadMethod();
accessMethods.add(m);
currentClass = m.getReturnType();
}
Comparator<T> comparator = Comparator.comparing((T entity) -> {
try {
Object result = entity;
for (Method method : accessMethods) {
result = method.invoke(result);
}
return (Comparable) result;
} catch (IllegalAccessException | InvocationTargetException e) {
throw new RuntimeException(e);
}
}, Comparator.nullsLast(Comparator.naturalOrder()));
if (order.isDescending())
return comparator.reversed();
return comparator;
}
}
public类ComparatorUtils{
公共静态比较器fromSort(排序,类类型){
最终迭代器orderIterator=sort.Iterator();
final Sort.Order Order=orderIterator.next();
比较器比较器=来自排序器(顺序、类型);
while(orderIterator.hasNext()){
comparator=comparator.ThenComparating(来自SortOrder(orderIterator.next(),type));
}
返回比较器;
}
SortOrder中的专用静态比较器(Sort.Order,类类型){
final List accessMethods=new ArrayList();
类别currentClass=类型;
对于(字符串属性:order.getProperty().split(“\\”)){
方法m=Objects.requireNonNull(BeanUtils.getPropertyDescriptor(currentClass,property)).getReadMethod();
增加(m);
currentClass=m.getReturnType();
}
比较器比较器=比较器。比较((T实体)->{
试一试{
对象结果=实体;
for(方法:accessMethods){
result=method.invoke(结果);
}
回报(可比)结果;
}捕获(IllegalAccessException | InvocationTargetException e){
抛出新的运行时异常(e);
}
},Comparator.nullsLast(Comparator.naturalOrder());
if(order.isDescending())
返回比较器。反转();
返回比较器;
}
}
你的意思是:“public Bar getBar()”?我打赌他是这么想的,否则这个问题就没有任何意义了。嗯,这不是一个JavaBeans编辑器,而是一个借用JavaBeans编辑器一些概念的web表单。