簡體   English   中英

@Nullable vs. Generics(Eclipse)

[英]@Nullable vs. Generics (Eclipse)

我想將一個實用程序方法引入Java 8.名為max的方法定義如下:

@SafeVarargs
public static final <E extends Comparable<E>> E max(final E... elements) {
    E result = null; // error
    for(final E e : elements) {
        if(result == null || result.compareTo(e) < 0) {
            result = e;
        }
    }
    return result;
}

現在Eclipse顯示錯誤:

空類型不匹配(類型注釋): null與自由類型變量E不兼容。

@Nullable以為將@Nullable添加到result的定義應該刪除錯誤,但顯然不是這種情況。 即使我另外使用@Nullable注釋整個方法,錯誤仍然存​​在。

順便說一句,我正在使用FindBugs的jsr-305.jar,並已配置Eclipse以尊重javax.annotation.Nonnull以及javax.annotation.Nullable 編輯:我在Lubuntu上運行Eclipse Luna 4.4.2和Oracle JDK 8 build 1.8.0_25-b17。

現在我的問題是:錯誤來自哪里? 如何在保持注釋和泛型類型定義的好處的同時擺脫它?

編輯:我剛剛添加了一個示例項目,其中使用了默認的eclipse注釋,它似乎有些工作(除了在result == null處生成警告,因為它錯誤地推斷結果在該點只能為null)。 所以這似乎是一個帶有非默認注釋類的Eclipse問題。 我用我自己的Eclipse的Nullable注釋副本重新測試它,並得到與上面相同的錯誤。

錯誤來自哪里?

我在文檔中找到了這個:

對應於無約束類型參數的類型變量需要悲觀檢查以確保所有合法替換的安全性:此類型既不能被認為是可空的也不是非空的。

 class C<T extends Number> { int consume(T t) { return t.intValue(); // NOT OK since T could be nullable } T provide() { return null; // NOT OK since T could require nonnull } } 

最后一點可能看起來令人驚訝,但請注意,無約束類型參數意味着我們可能不會假設任何關於由相應類型變量表示的類型的null。 更重要的是:我們必須積極支持可空和非空類型。 另一方面,這只是擴展了現有規則,即與無界類型變量兼容的唯一類型是類型變量本身。 要在null分析的上下文中解釋這種情況,編譯器將針對provide()中的返回引發以下錯誤:

在實例化泛型類型或調用泛型方法時,必須遵守type參數提出的約束。

如何在保持注釋和泛型類型定義的好處的同時擺脫它?

將@Nullable添加到<E extends Comparable<E>> ,就像這樣

@SafeVarargs
public static final  <@Nullable E extends Comparable<E>> E max(final E... elements) {
    E result = null; // no error
    for(final E e : elements) {
        if(result == null || result.compareTo(e) < 0) {
            result = e;
        }
    }
    return result;
}

Tja,可選。 如果varargs數組為空,怎么回事?

public static final <E extends Comparable<E>> Optional<E> max(final E... elements) {
    Optional<E> result = Optional.empty();
    for(final E e : elements) {
        if(!result.isPresent() || result.get().compareTo(e) < 0) {
            result.set(e);
        }
    }
    return result;
}

或者至少需要一個參數。

public static final <E extends Comparable<E>> E max(final E first, final E... elements) {
    E result = first;
    for (final E e : elements) {
        if (/*result != null ||*/ result.compareTo(e) < 0) {
            result = e;
        }
    }
    return result;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM