Może to być coś powszechnego i trywialnego, ale wydaje mi się, że mam problem ze znalezieniem konkretnej odpowiedzi. W C # istnieje koncepcja delegatów, która jest silnie związana z ideą wskaźników funkcji z C ++. Czy w Javie jest podobna funkcjonalność? Biorąc pod uwagę, że wskaźniki są nieco nieobecne, jaki jest najlepszy sposób na to? Żeby było jasne, mówimy tutaj o pierwszej klasie.
java
pointers
delegates
function-pointers
dreadwail
źródło
źródło
this::myMethod
jest semantycznie taka sama jak tworzenie lambdyparamA, paramB -> this.myMethod(paramA, paramB)
.Odpowiedzi:
Idiom Java dla funkcjonalności podobnej do wskaźnika funkcji to anonimowa klasa implementująca interfejs, np
Aktualizacja: powyższe jest konieczne w wersjach Java przed Java 8. Teraz mamy dużo ładniejsze alternatywy, a mianowicie lambdy:
i odniesienia do metod:
źródło
std::bind
, co wiąże parametry z funkcjami i zwraca wywoływalny obiekt. Nie mogę bronić C na tej podstawie, ale C ++ jest naprawdę lepszy niż Java.Możesz zastąpić wskaźnik funkcji interfejsem. Powiedzmy, że chcesz przejrzeć kolekcję i zrobić coś z każdym elementem.
To jest interfejs, który moglibyśmy przekazać niektórym, powiedzmy, CollectionUtils2.doFunc (Collection c, IFunction f).
Jako przykład załóżmy, że mamy zbiór liczb i chciałbyś dodać 1 do każdego elementu.
źródło
Możesz użyć do tego refleksji.
Jako parametr przekaż obiekt i nazwę metody (jako ciąg), a następnie wywołaj metodę. Na przykład:
A potem użyj go jak w:
Oczywiście sprawdź wszystkie wyjątki i dodaj potrzebne rzuty.
źródło
Nie, funkcje nie są obiektami pierwszej klasy w Javie. Możesz zrobić to samo, implementując klasę handlera - w ten sposób zaimplementowane są wywołania zwrotne w Swingu itp.
Istnieją jednak propozycje zamknięć (oficjalna nazwa tego, o czym mówisz) w przyszłych wersjach java - Javaworld ma ciekawy artykuł.
źródło
To przywodzi na myśl Egzekucję Steve'a Yegge'a w Królestwie Rzeczowników . Zasadniczo stwierdza się, że Java potrzebuje obiektu dla każdej akcji i dlatego nie ma jednostek „tylko czasownikowych”, takich jak wskaźniki funkcji.
źródło
Aby osiągnąć podobną funkcjonalność, możesz użyć anonimowych klas wewnętrznych.
Gdybyś miał zdefiniować interfejs
Foo
:Utwórz metodę,
bar
która otrzyma `` wskaźnik funkcji '' jako argument:Na koniec wywołaj metodę w następujący sposób:
źródło
Java8 wprowadziła lambdy i odwołania do metod . Więc jeśli twoja funkcja pasuje do funkcjonalnego interfejsu (możesz stworzyć własny), możesz w tym przypadku użyć odwołania do metody.
Java udostępnia zestaw wspólnych interfejsów funkcjonalnych . mając na uwadze, że możesz wykonać następujące czynności:
źródło
alias
: np.public List<T> collect(T t) = Collections::collect
W Javie nie ma czegoś takiego. Będziesz musiał opakować swoją funkcję w jakiś obiekt i przekazać referencję do tego obiektu, aby przekazać referencję do metody na tym obiekcie.
Składniowo można to w pewnym stopniu złagodzić, stosując klasy anonimowe zdefiniowane lokalnie lub klasy anonimowe zdefiniowane jako zmienne składowe klasy.
Przykład:
źródło
Zaimplementowałem obsługę callback / delegate w Javie przy użyciu refleksji. Szczegóły i działające źródło są dostępne na mojej stronie internetowej .
Jak to działa
Mamy klasę główną o nazwie Callback z zagnieżdżoną klasą o nazwie WithParms. API, które potrzebuje wywołania zwrotnego, przyjmie obiekt Callback jako parametr i, jeśli to konieczne, utworzy Callback.WithParms jako zmienną metody. Ponieważ wiele zastosowań tego obiektu będzie rekurencyjnych, działa to bardzo czysto.
Ponieważ wydajność nadal ma dla mnie wysoki priorytet, nie chciałem być zmuszony do tworzenia jednorazowej tablicy obiektów do przechowywania parametrów dla każdego wywołania - w końcu w dużej strukturze danych mogą znajdować się tysiące elementów, a przetwarzanie wiadomości W scenariuszu możemy skończyć przetwarzaniem tysięcy struktur danych na sekundę.
Aby zapewnić ochronę wątków, tablica parametrów musi istnieć unikalnie dla każdego wywołania metody API, a dla wydajności powinna być używana taka sama dla każdego wywołania wywołania zwrotnego; Potrzebowałem drugiego obiektu, który byłby tani do utworzenia, aby powiązać wywołanie zwrotne z tablicą parametrów do wywołania. Ale w niektórych scenariuszach wywołujący miałby już tablicę parametrów z innych powodów. Z tych dwóch powodów tablica parametrów nie należała do obiektu Callback. Również wybór wywołania (przekazanie parametrów jako tablica lub jako pojedyncze obiekty) należy do API przy użyciu wywołania zwrotnego, umożliwiającego użycie dowolnego wywołania, które najlepiej pasuje do jego wewnętrznego działania.
Zagnieżdżona klasa WithParms jest zatem opcjonalna i służy dwóm celom: zawiera tablicę obiektów parametrów potrzebnych do wywołań zwrotnych oraz udostępnia 10 przeciążonych metod invoke () (z 1 do 10 parametrami), które ładują tablicę parametrów, a następnie wywołać cel wywołania zwrotnego.
źródło
Sprawdź, jak domknięcia zostały zaimplementowane w bibliotece lambdaj. W rzeczywistości zachowują się bardzo podobnie do delegatów C #:
http://code.google.com/p/lambdaj/wiki/Closures
źródło
W porównaniu z większością osób tutaj jestem nowy w Javie, ale ponieważ nie widziałem podobnej sugestii, mam inną alternatywę do zasugerowania. Nie jestem pewien, czy to dobra praktyka, czy nie, a nawet zasugerowałem wcześniej i po prostu tego nie rozumiem. Po prostu to lubię, ponieważ uważam, że jest samoopisowe.
następnie w zależności od aplikacji przypisz
itp.
i zadzwoń
źródło