簡體   English   中英

使用下限通配符時類型不兼容

[英]Incompatible types when using lower bound wildcard

我不明白為什么我的代碼有編譯錯誤:

private static <T> Consumer<T> f3()
{
    return t -> {};
}

private static <T> Consumer<? super T> f4()
{
    return t -> {};
}


@Test
public void test()
{
    Consumer<Integer> action3 = f3();
    Consumer<Integer> action4 = f4(); // ERROR
}

來自Javac 1.8.0_161的錯誤:

錯誤:(84,36)java:不兼容的類型:不存在類型為T變量的實例,因此java.util.function.Consumer<? super T> java.util.function.Consumer<? super T>符合java.util.function.Consumer<java.lang.Void>

誰能解釋這個錯誤? 謝謝。

編輯我試圖簡化我的示例,並且通過使其過於簡單而犯了一個錯誤。 我感興趣的是由IntelliJ輸出的對此錯誤的解釋:

private static <T> BiConsumer<T, ? super Throwable> f1(Consumer<? super Throwable> consumer)
{
    return null;
}

private static <T> BiConsumer<? super T, ? super Throwable> f2(Consumer<? super Throwable> consumer)
{
    return null;
}

@Test
public void test()
{
    BiConsumer<? super Integer, ? super Throwable> action1 = f1(throwable -> { });
    BiConsumer<? super Integer, ? super Throwable> action2 = f2(throwable -> { });  // ERROR HERE
}

IntelliJ認為這是一個錯誤,因為“推斷變量T具有不兼容的界限:等式約束:T下界:整數”。 但是在編譯時,這很好,沒有錯誤。 這是實際上有效的Java代碼,只是IntelliJ中的錯誤嗎? 謝謝。

Consumer<? super Something> Consumer<? super Something>不是Consumer<Integer>

編譯器不知道Consumer類上沒有生產器方法,因此它可能會阻止您將其用作生產器。

就類型推斷規則而言,例如, ConsumerList之間沒有區別。 因此,阻止您編寫以下內容的相同規則也將阻止您執行操作:

List<? super Integer> c = Arrays.asList("");
List<Integer> d = c;        // Compiler error; let's pretend it works.
Integer i = d.get(0);       // ClassCastException!

您的編輯答案:

我懷疑這是intellij中的錯誤。 如果刪除變量聲明,然后選擇表達式並按Ctrl + Alt + V提取變量,則它將選擇以下類型:

BiConsumer<? super Object, ? super Throwable> biConsumer = f2(throwable -> {});

盡管剛剛選擇了它,但它仍將lambda突出顯示為錯誤。

請嘗試File-> Invalidate Caches並重新啟動。

暫無
暫無

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

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