2016-11-21 66 views
0

我有一個派生自java.util.concurrent.AbstractExecutorService的類。我的課程覆蓋shutdownNow()。一切都編譯並運行良好。@NonNullByDefault返回類型與從ExecutorService.shutdownNow()返回的'List <Runnable>'不兼容(不匹配null約束)

我將[email protected]添加到課程中。我設法修復了除shutdownNow()上的1個錯誤之外的所有錯誤和警告。該錯誤消息說...

的返回類型是「列表」,從不相容返回ExecutorService.shutdownNow() (錯配空約束)

快速修正都沒有任何幫助。

這裏是違規的代碼。

@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()不是問題。這只是簡化了再現相同錯誤消息的實際代碼。

下面是代碼的圖片。

enter image description here

回答

1

似乎ExecutorService不在任何@NonNullByDefault的範圍內,對不對?

此外,ExecutorService宣佈List<Runnable> shutdownNow()

但是,覆蓋受@NonNullByDefault的影響,其有效簽名爲@NonNull List<@NonNull Runnable> shutdownNow()

不幸的是,速戰速決僅關於第一個@NonNull,而在類型參數Runnable註釋其實是造成不兼容:

我們不知道的ExecutorService.shutdownNow()預期的語義:應客戶期望可爲空或非空返回列表中的元素?假設List<@NonNull Runnable>將打破shutdownNow()的潛在呼叫者喜歡將null插入結果列表(忽略這將意味着奇怪的設計)。

要使此重寫類型安全,應首先在超接口上引入null註釋(在本例中使用外部註釋),然後讓實現跟隨套件。

如果標註的超接口是不可行的任何原因,即與List<Runnable>的「傳統」型持續的需要,那麼空默認可以說@NonNullByDefault({}),並手動添加@NonNull它在哪裏被取消這一個方法仍然期望。

相關問題