2015-09-21 46 views
19

tôi học tính năng mới của Java 8.Java 8 có thể triển khai giao diện trực tiếp để tham khảo phương pháp không?

tôi đang chơi với các ví dụ khác nhau và tôi đã tìm thấy một hành vi kỳ lạ:

public static void main(String[] args) {  
    method(Test::new); 
} 
static class Test{ 
} 

private static void method(Supplier<Test> testSupplier){ 
    Test test = testSupplier.get(); 
} 

Mã này biên dịch thành công nhưng tôi không có ý tưởng như thế nào nó hoạt động.

Tại sao Test::new được chấp nhận làm Nhà cung cấp?

giao diện Nhà cung cấp trông rất đơn giản:

@FunctionalInterface 
public interface Supplier<T> {  
    T get(); 
} 
+2

Để tự động triển khai loại AFAIK nào có con thú này: ['java.lang.invoke.LambdaMetafactory'] (https://docs.oracle.com/javase/8/docs/api/java/lang/ Gọi/LambdaMetafactory.html) – zapl

+3

Lưu ý rằng một khai báo lớp "rỗng", chẳng hạn như cho 'lớp Test' của bạn, ngầm có một hàm tạo no-arg. Đó là lý do tại sao bạn có thể viết 'new Test()' và có nó hoạt động, bất kỳ lý do tại sao một lambda hoặc phương thức tham chiếu đến constructor này hoạt động. –

+0

@Sotirios Delimanolis có lẽ bình luận đầu tiên cho câu hỏi được liên kết là phù hợp hơn – gstackoverflow

Trả lời

19

Giao diện Supplier có một phương pháp duy nhất (chức năng) rằng:

  • không mất bất kỳ thông số;
  • trả về một đối tượng.

Do đó, bất kỳ phương pháp nào tuân thủ hai điểm đó, đều tuân thủ hợp đồng chức năng của Supplier (vì các phương thức sẽ có cùng chữ ký).

Ở đây, phương pháp được đề cập là tham chiếu phương pháp. Nó không có tham số và trả về một phiên bản mới của Test. Bạn có thể viết lại nó cho:

method(() -> new Test()); 

trong đường cú pháp cho biểu thức lambda này.

+0

Vì vậy, nếu trả lời câu hỏi từ chủ đề của tôi - Có, tham chiếu phương pháp được phát minh để thực hiện giao diện động. – gstackoverflow

3

Nó có thể là một Function, chứ không phải là một nhà cung cấp, nếu một cuộc tranh cãi là bắt buộc. Nhưng các tham chiếu phương thức có thể ám chỉ đến các nhà xây dựng theo cùng một cách mà chúng đề cập đến các phương thức; họ chỉ có một cái tên hài hước (new).

Từ the Java Tutorial, có bốn loại tài liệu tham khảo phương pháp:

 
Kind        Example 
------------------------------- ------------------------------------ 
Reference to a static method  ContainingClass::staticMethodName 
Reference to an instance method containingObject::instanceMethodName 
of a particular object 
Reference to an instance method ContainingType::methodName 
of an arbitrary object of a 
particular type 
Reference to a constructor  ClassName::new 
11

Test::new là tham chiếu phương pháp. Thay vì thêm một lời giải thích mới, bạn nên xem hướng dẫn cho method references vì nó giải thích chúng khá tốt.

Câu trả lời trực tiếp cho câu hỏi của bạn là Supplier là giao diện chức năng - có nghĩa là nó có một phương thức không mặc định. Hàm khởi tạo cho Test có chữ ký giống hệt nhau (không có đối số, trả về Test) và do đó có thể được tham chiếu trực tiếp để tạo một số vô danh Supplier.

Có bốn hương vị của tham chiếu phương pháp: xem hướng dẫn để hiểu tất cả.

+0

Do đó tính năng này cho phép các lớp cũ có thể triển khai giao diện mới được tạo. WoW! – gstackoverflow

+1

@gstackoverflow Đúng vậy. Miễn là các chữ ký phù hợp với bạn có thể tham khảo phương pháp để tạo ra một thể hiện của giao diện. Khi sử dụng tốt nó có thể cải thiện đáng kể khả năng đọc mã. – sprinter

Các vấn đề liên quan