2017-08-16 49 views
27

Przy zastosowaniu funkcji map w Javie można wykonać następujące czynności:Jak użyć odwołania do metody do importu statycznego?

import com.example.MyClass; 

someStream.map(MyClass::myStaticMethod) 

ale w moim projekcie czasami wykorzystać import statycznych, jak mogę odwołać myStaticMethod gdy import jest statyczny?

bym, że to będzie działać, ale tak nie jest:

import static com.example.MyClass.myStaticMethod; 

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

Dlaczego to nie działa? Czy utknąłem z użyciem pierwszego przykładu lub czy istnieją inne rozwiązania?

Odpowiedz

29

Spójrzmy na odpowiednią część specyfikacji języka Java, 15.13. Method Reference Expressions.

wymienia się następujące sposoby odniesienia tworzyć metoda:

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

pamiętać, że wszystkie z nich zawierają :: token.

Ponieważ argument do nie obejmuje ::, nie jest prawidłowym odwołaniem do metody.

Sugeruje to, że trzeba importować MyClass (może oprócz do statycznej importu, jeśli to twoje preferencje) i odnoszą się do sposobu jak MyClass::myStaticMethod.

+1

Przyjemny sposób myślenia o problemie poprzez odniesienie do JLS! Ale mapa może również obsługiwać inne argumenty, takie jak lambda, która również nie ma ::. Czy istnieje bardziej abstrakcyjny typ, który reprezentuje to, co mapa zaakceptuje jako argument? Który byłby – Xeli

3

Posiadanie statycznego importu metody nie ma wpływu na sposób, w jaki definiujesz odniesienie do metody.

Tak więc, jeśli chcesz go do pracy, powinien on wyglądać dokładnie tak samo jak przed wprowadzeniem statycznego importowania:

MyClass::myStaticMethod 
-2

ze statycznym importu metody można tylko zadzwonić, ale nie odnoszą się do to. Dla stream(). Map() potrzebuje referencji do funkcji, aby mogła wywołać ją dla każdego wpisu.

4

Cóż, nie kompiluje się, ponieważ JLS tak mówi. Ale to nie może się nawet skompilować, ponieważ byłoby to zwykłe wywołanie metody , a nie odwołanie do metody , które jest zdefiniowane TYLKO przy użyciu notacji ::, czy jest to statyczna lub używana instancja.

To interesujący aspekt, którego nie można rozwiązać - może być w tej chwili. Nie ma obsługi języków, aby zdefiniować coś takiego:

MethodRef <Class, Method> ref = ... 

Później używaj tego w taki sposób, w jaki chcesz. Ale nie sądzę, że byłoby to możliwe, ponieważ musiałbyś w jakiś sposób zdefiniować typy parametrów i typ zwracania, ponieważ byłoby to potrzebne, aby sprawdzić, czy pasuje do wielu innych miejsc. Podobnie jak Predicate<String> i Function<String, Boolean>, które potencjalnie mogą mieć zastosowanie do tego samego method reference.