0

我有一个派生自java.util.concurrent.AbstractExecutorService. 我的班级覆盖shutdownNow(). 一切都编译并运行良好。

我加入org.eclipse.jdt.annotation.@NonNullByDefault了课堂。我设法修复了所有错误和警告,除了shutdownNow(). 错误消息说...

返回类型与 ExecutorService.shutdownNow() 返回的“List”不兼容(不匹配空约束)

快速修复没有任何帮助。

这是有问题的代码。

@NonNullByDefault    // Adding this causes an error
public abstract class ShutdownThreadPool extends AbstractExecutorService implements ExecutorService
{
   @Override
   public List<Runnable> shutdownNow()   // The error is on this line
   {
      return(Collections.emptyList());
   }
}

注意: Collections.emptyList() 不是问题。它只是重现相同错误消息的实际代码的简化。

这是代码的图像。

在此处输入图像描述

4

1 回答 1

1

似乎ExecutorService不在 any 的范围内@NonNullByDefault,对吧?

此外,ExecutorService声明List<Runnable> shutdownNow().

但是,覆盖会受到@NonNullByDefault其有效签名的影响@NonNull List<@NonNull Runnable> shutdownNow()

不幸的是,快速修复只考虑第一个@NonNull,而类型参数上的注释Runnable实际上导致了不兼容:

我们不知道ExecutorService.shutdownNow(): 的预期语义,客户端应该在返回的列表中期望可空或非空元素吗?假设List<@NonNull Runnable>会破坏shutdownNow()喜欢插入null结果列表的潜在调用者(忽略这暗示的奇怪设计)。

为了使这种覆盖类型安全,应该首先在超接口上引入空注释(在这种情况下使用外部注释),然后让实现遵循套件。

如果由于任何原因注释超级接口不可行,即List<Runnable>希望继续使用“遗留”类型,则可以通过说取消此方法的空默认值@NonNullByDefault({}),并手动添加@NonNull仍然需要的位置。

于 2016-11-22T17:29:49.570 回答