Java 如何获取嵌套属性的方法?

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

我有一个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
的类,但它的
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表单。