【问题标题】:Java 8, stream filter, reflect, NoSuchMethodException [duplicate]Java 8,流过滤器,反射,NoSuchMethodException [重复]
【发布时间】:2018-08-08 19:45:09
【问题描述】:

我有这个代码

List<JComponent> myList = new ArrayList<>();
fillmyList(myList); //Some method filling the list
try{
    menuList.stream()
    .filter(m->m.getClass().getMethod("setFont", new Class[]{Font.class}) != null) //unreported exception NoSuchMethodException; must be caught or declared to be thrown
    .forEach(m -> m.setFont(someFont));
}
catch (NullPointerException |  NoSuchMethodException e) {} //exception NoSuchMethodException is never thrown in body of corresponding try statement

但是,我有这个错误信息:

Exception in thread "AWT-EventQueue-0" java.lang.RuntimeException: Uncompilable source code - exception java.lang.NoSuchMethodException is never thrown in body of corresponding try statement

如何解决?

【问题讨论】:

  • 你需要在 lambda 函数的主体中捕获它。
  • 请教我怎么做...
  • 你的逻辑有缺陷。 getMethod() 永远不会返回 null。
  • 请注意,getMethod 永远不会返回 null,所有 JComponent 都有一个 setFont() 方法,因为它是在 JComponent 中声明的,NullPointerException 永远不应被捕获,并且 catch 块永远不应为空:这只是隐藏了错误并使它们很难诊断。这段代码没有意义。
  • @JBNizet 我花了一段时间才意识到这段代码实际上是在调用 setFont 方法,而 .forEach(m -&gt; m.setFont(someFont)) 中没有反射,这使得整个 filter 步骤更加荒谬,因为编译器已经声明 setFont 方法始终存在于所有流元素中……

标签: java reflection lambda java-stream


【解决方案1】:

这不是异常,而是编译错误。
您必须捕获可能引发异常的 lambda 主体,而不是整个流。

下面是一个在filter() 中为引发异常的流元素返回false 的示例:

myList.stream()
      .filter(m -> {
          try {
              return m.getClass()
                      .getMethod("setFont", new Class[] { Font.class }) != null;
          } catch (NoSuchMethodException | SecurityException e) {
              // log the exception
              return false;
          }
      })

您当然可以使用不同的策略,如抛出 RuntimeException 并停止处理。

【讨论】:

  • 请注意,没有必要将Font.classnew Class[] { Font.class } 包装起来,因为getMethod 是一个varargs 方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-02
  • 2018-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多