2017-08-16 33 views
27

Khi sử dụng chức năng bản đồ trong java Tôi có thể làm như sau:Làm cách nào để sử dụng tham chiếu phương thức trên một lần nhập tĩnh?

import com.example.MyClass; 

someStream.map(MyClass::myStaticMethod) 

nhưng trong dự án của tôi đôi khi chúng ta sử dụng hàng nhập khẩu tĩnh, làm thế nào tôi có thể tham khảo các myStaticMethod khi nhập khẩu là tĩnh?

Tôi nghĩ rằng điều này sẽ làm việc nhưng nó không:

import static com.example.MyClass.myStaticMethod; 

someStream.map(myStaticMethod); //does not compile 

Tại sao điều này không làm việc? Tôi có bị mắc kẹt không khi sử dụng ví dụ đầu tiên hoặc có các giải pháp khác.

Trả lời

29

Hãy xem phần liên quan của Đặc tả ngôn ngữ Java, 15.13. Method Reference Expressions.

Nó liệt kê các cách sau đây để tham khảo tạo phương pháp:

MethodReference: 
    ExpressionName :: [TypeArguments] Identifier 
    ReferenceType :: [TypeArguments] Identifier 
    Primary :: [TypeArguments] Identifier 
    super :: [TypeArguments] Identifier 
    TypeName . super :: [TypeArguments] Identifier 
    ClassType :: [TypeArguments] new 
    ArrayType :: new 

Lưu ý rằng tất cả trong số họ bao gồm một thẻ ::.

Vì đối số cho someStream.map(myStaticMethod) không bao gồm ::, đó không phải là tham chiếu phương pháp hợp lệ.

Điều này cho thấy bạn cần phải nhập MyClass (có lẽ ngoài vào nhập tĩnh, nếu đó là tùy chọn của bạn) và tham khảo phương thức là MyClass::myStaticMethod.

+1

Cách hay để suy nghĩ về vấn đề này bằng cách tham chiếu JLS! Nhưng bản đồ cũng có thể xử lý các đối số khác, như lambda cũng không có một ::. Có một loại trừu tượng hơn đại diện cho những gì một bản đồ sẽ chấp nhận làm đối số? Mà sẽ s – Xeli

3

Việc nhập tĩnh phương thức không ảnh hưởng đến cách bạn xác định phương thức tham chiếu đến phương thức đó.

Vì vậy, nếu bạn muốn nó để làm việc, nó sẽ giống hệt nhau giống như trước đây giới thiệu việc nhập khẩu tĩnh:

MyClass::myStaticMethod 
-2

Với nhập khẩu tĩnh của một phương pháp mà bạn chỉ có thể gọi nhưng không đề cập đến nó. Đối với luồng(). Map() nó cần tham chiếu đến một hàm để nó có thể gọi nó cho mọi mục nhập.

4

Vâng nó không biên dịch vì JLS nói như vậy. Nhưng điều đó thậm chí không thể biên dịch được vì nó sẽ là lời gọi phương thức đồng bằng và không phải là tham chiếu phương thức - được chỉ định bằng ký hiệu ::, có thể là tĩnh hoặc phiên bản được sử dụng.

Vẫn còn một khía cạnh thú vị, một khía cạnh mà bạn không thể giải quyết - có thể tại thời điểm này. Không có hỗ trợ ngôn ngữ để xác định một cái gì đó như:

MethodRef <Class, Method> ref = ... 

Và sau đó sử dụng theo cách bạn muốn. Nhưng tôi thậm chí không nghĩ rằng điều đó là có thể, bởi vì bạn cũng sẽ phải định nghĩa các kiểu tham số và kiểu trả về bằng cách nào đó, bởi vì điều này sẽ cần thiết để xem nó có khớp với nhiều vị trí khác không. Giống như Predicate<String>Function<String, Boolean> có khả năng sẽ áp dụng cho cùng một method reference.

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