【问题标题】:BeanUtils to call the size() method of a collection (which is not a setter)BeanUtils 调用集合的 size() 方法(不是 setter)
【发布时间】:2012-06-06 22:02:45
【问题描述】:

我有一个带有 getter 和 setter 的类:

class A
{
  private Set<Offers> offers;

  public Set<Offers> getOffers(){
    return offers;
  }

  public void setOffers(Set<Offers> offers){
    this.offers = offers;
  }

}

现在我想使用 Apache Commons PropertyUtils 获取报价的 size():

PropertyUtils.getProperty(myAInstance, "offers.size");

这应该基本上与以下内容相同:

myAInstance.getOffers().size();

但是使用 PropertyUtils 不起作用并给了我一个:

java.lang.NoSuchMethodException:类上的未知属性“大小” '类 java.util.LinkedHashSet'

对其他对象的所有 getter 和 setter 使用 PropertyUtils 工作正常。

我怀疑这是因为 Collection 的 size() 方法没有遵循 getXXX 和 setXXX bean 约定。

还有其他方法可以使用 PropertyUtils / 或 BeanUtils(或 Apache Commons 中的其他任何东西)来调用我的集合的 size() 方法吗?

谢谢 克里斯托夫

【问题讨论】:

    标签: java reflection apache-commons-beanutils


    【解决方案1】:

    PropertyUtils 被命名为“PropertyUtils”是有原因的。它适用于 java bean 约定。 “size()”方法不符合该约定,因此不能将其称为属性。

    也许您最好使用支持属性导航和函数调用的 MVEL 或 GroovyScript。这是 mvel 的示例,应该可以工作

    Integer size = (Integer) MVEL.eval("offers.size()", instanceOfA);
    

    试一试。

    【讨论】:

    • 是的,我知道 MVEL 不是 apache commons,但它使用的是 Apache 2.0 许可证,我相信这正是所有 commons 包都应该使用的。
    • 谢谢,我意识到表达式语言更像是我在寻找的东西,并且我认为 PropertyUtils 是错误的。我会试试 MVEL。
    【解决方案2】:

    一种解决方法(无法让它工作)+我同意 Dave '不完全清楚你为什么想要'

    将此添加到您的 A 类

    public int getOfferSize(){
        return offers == null ? 0 : offers.size();
    }
    

    然后使用

    PropertyUtils.getProperty(myAInstance, "offerSize");
    

    【讨论】:

      【解决方案3】:

      虽然它确实提供了一些围绕反射 API 的薄包装器,但并不完全清楚您为什么要这样做。

      您需要使用MethodUtils class,特别是invokeExactMethodinvokeMethod variants 之一。

      【讨论】:

      • 嗯,似乎 MethodUtils 和 invokeMethod 变体不支持方法的嵌套定义。我希望能够说 invokeMethod("offers.size") 并且我希望它调用两个方法 getOffers().getSize(),这两个方法都没有任何参数。但这也给了我一个:没有这样的可访问方法:对象上的 offer.size()
      • @Christoph 这不是一种表达式语言,除了 OGNL(现在是一个 Apache 项目)和 JSP EL 的东西,我不知道 Commons 中的任何内容。将 bean utils 和 property utils 组合在一个微不足道的实用方法中真的那么难吗?或者您应该采取另一种方法,例如编写脚本。
      • 好的,谢谢戴夫。看待它的“表达语言”方式是有道理的。嗯,好吧,我想起初我会采用 D3mon-1stVFW 的解决方法,并尝试马特提到的 MVEL。我认为 MVEL 更符合我的要求。关于 Property/BeanUtils 的组合:它并不太难(而且我已经破解了它......)但认为这个功能已经提供但也许我是盲目地找到它...... :) 谢谢
      • @Christoph MVEL 也比 OGNL 更快,并且具有相似的表达能力。你可以做一些……“有趣”的事情。
      【解决方案4】:

      您可以直接通过良好的旧反射来做到这一点,避免使用任何库。

      首先,你得到 getter:

      Method get = A.class.getDeclaredMethod("getOffers");
      

      现在您调用 getter 并获取表示集合的对象。然后你创建一个新的 Method 来表示 Set 中定义的 size 方法:

      Object setFromA= get.invoke(yourAObject);
      Method size = Set.class.getDeclaredMethod("size");
      

      最后,将方法转换为 setFromA 并获取大小,将 setFromA 对象转换为所需的类型:

      Integer listSize = (Integer) size.invoke(get.getReturnType().cast(setFromA));
      

      【讨论】:

      • 是的,这就是我现在破解它的方式,但我喜欢 PropertyUtils 的嵌套属性语法,因为 90% 的东西都是 getter/setter。我要么坚持使用 getter/setter,要么尝试像 MVEL 这样​​的表达语言。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-04-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-23
      • 1970-01-01
      相关资源
      最近更新 更多