簡體   English   中英

為什么類型推斷對於lambda失敗,但成功進行等效的方法引用?

[英]Why does type inference fail for lambda, but succeed for equivalent method reference?

我正在使用lambda在下面的Java程序中實現一個功能接口。 當lambda作為參數傳遞給泛型方法時,編譯器會標記“不兼容類型”錯誤,因為它推斷lambda實現了Func <Shape>接口,該接口讓編譯器將lambda參數(“thing”)解釋為當lambda嘗試將其傳遞給需要Round類型參數的方法(testRound)時,為Shape類型。 這個錯誤對我有意義。

但是等效方法引用不會引發錯誤消息。 我一直誤以為lambda和可以替換lambda的方法引用是可以互換的。 在這里,事實並非如此。

public class Main
{
    public static void main(String... args)
    {
        methodB(thing -> Main.testRound(thing)); // incompatible types
        methodB(Main::testRound);                // no problem here
    }

    static <T extends Shape> void methodB(Func<T> function)
    {
    }

    static boolean testRound(Round thing)
    {
        return true;
    }
}

interface Func<T>
{
    boolean test(T ob);
}

class Shape
{
}

class Round extends Shape
{
}

當lambda失敗時,為什么方法引用成功?

UPDATE

Vince Emigh在下面找到了我已經標記為接受的答案。 雖然這不是我的問題的一部分,但是有四種方法可以解決這樣一個事實:如果一個人真的堅持使用lambda,那么lambda只被推斷為類型為Func<Shape>

// Use a type witness.

Main.<Round>methodB(thing -> testRound(thing));

// Make the lambda's argument type explicit.

methodB((Round thing) -> testRound(thing));

// Cast the argument.

methodB(thing -> testRound((Round)thing));

// Store the lambda reference in a Func<Round> variable.

Func<Round> lambda = thing -> testRound(thing);
methodB(lambda);

我沒有看到任何理由更喜歡其中一個而不是方法參考,除非有人認為lambdas的密度稍低(並且可能更具可讀性)。 但是,如果你想要它們,它們就在那里。

來自JLS§15.13.2

與lambda表達式不同,方法引用可以與泛型函數類型(即具有類型參數的函數類型)一致。 這是因為lambda表達式需要能夠聲明類型參數,並且沒有語法支持這一點; 而對於方法參考,則不需要此類聲明。

lambda表達式引發錯誤,因為沒有指定類型參數。 這會導致T被編譯為Shape (如你的文章中所述),因為沒有什么可以幫助推斷出參數的類型。

至於方法引用,因為可以從方法的參數推斷出類型,所以不需要顯式類型參數,如上面的JLS語句中所述。

暫無
暫無

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

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