2016-04-18 14 views
12

Tôi đã tò mò tại sao một lambda với kiểu trả về không thể được đúc thành một Runnable trong khi tham chiếu phương thức không trống có thể.Quy tắc đúc Lambda

Runnable r1 =() -> 1; // not allowed 
// error: incompatible types: bad return type in lambda expression 
// int cannot be converted to void 

Runnable r2 = ((Supplier)() -> 1)::get; // allowed 

Trả lời

14

Giao diện Runnable xác định phương pháp run với kiểu trả về void. Trong biểu thức lambda có nghĩa là phần sau mũi tên -> phải là câu lệnh . Điều này được giải thích trong JLS §15.27.3:

Nếu kết quả của loại hàm bị vô hiệu, thân lambda là biểu thức câu lệnh (§14.8) hoặc khối tương thích khoảng trống.

JLS $14.5 xác định rõ cú pháp của câu lệnh. Như đã giải thích ở trên, nó phải là "ExpressionStatement" (§ 14.8). Nhìn vào đó, bạn có thể thấy rằng một chữ đơn giản không phải là một biểu thức đầy đủ, nhưng một lời gọi phương thức là (ngay cả khi nó trả về một cái gì đó).

+1

Bạn có thể chỉ ra nơi trong JLS được đề cập rằng, trong trường hợp đó, "phần sau mũi tên' -> 'phải là _statement_"? Tôi đang tìm kiếm nó. – Tunaki

+2

@Tunaki Tìm thấy nó, đó là [§15.27.3] (https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.27.3). – RealSkeptic

+1

@RealSkeptic Ha hoàn toàn thực sự: * Nếu kết quả của kiểu hàm bị vô hiệu, phần tử lambda là biểu thức câu lệnh (§14.8) hoặc khối tương thích void. * Và biểu thức chính không phải là biểu thức câu lệnh (và isn ' t một khối). – Tunaki