Jaki jest najbliższy zamiennik wskaźnika funkcji w Javie?

Mam metodę, która ma około 10 linijek kodu. Chcę stworzyć więcej metod, które robią dokładnie to samo, z wyjątkiem małych obliczeń, które zmienią jedną linię kodu. Jest to idealna aplikacja do przekazywania wskaźnika funkcji w celu zastąpienia tej jednej linii, ale Java nie ma wskaźników funkcji. Jaka jest moja najlepsza alternatywa?

Author: Bill the Lizard, 2008-09-23

22 answers

Anonymous inner class

Powiedz, że chcesz mieć funkcję przekazaną z String param, która zwraca int.
Najpierw musisz zdefiniować interfejs z funkcją jako jego jedynym członkiem, jeśli nie możesz ponownie użyć istniejącego.

interface StringFunction {
    int func(String param);
}

Metoda pobierająca wskaźnik zaakceptowałaby StringFunction instancję w ten sposób:

public void takingMethod(StringFunction sf) {
   int i = sf.func("my string");
   // do whatever ...
}

I byłoby tak nazywane:

ref.takingMethod(new StringFunction() {
    public int func(String param) {
        // body
    }
});

EDIT: w Javie 8 można go nazwać wyrażeniem lambda:

ref.takingMethod(param -> bodyExpression);
 271
Author: sblundy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-31 05:02:02

Dla każdego "wskaźnika funkcji" stworzyłbym małą klasę functor , która implementuje twoje obliczenia. Zdefiniuj interfejs, który zaimplementują wszystkie klasy i przekaż instancje tych obiektów do większej funkcji. Jest to kombinacja "wzorca poleceń" i "wzorca strategii".

@sblundy przykład jest dobry.

 32
Author: Blair Conrad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:47:07

Gdy istnieje predefiniowana liczba różnych obliczeń, które można wykonać w tej jednej linii, użycie enum jest szybkim, ale jasnym sposobem na wdrożenie wzorca strategii.

public enum Operation {
    PLUS {
        public double calc(double a, double b) {
            return a + b;
        }
    },
    TIMES {
        public double calc(double a, double b) {
            return a * b;
        }
    }
     ...

     public abstract double calc(double a, double b);
}

Oczywiście deklaracja metody strategii, jak również dokładnie jedna instancja każdej implementacji są zdefiniowane w jednej klasie / pliku.

 28
Author: javashlook,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-27 00:16:31

Musisz utworzyć interfejs, który zapewnia funkcje,które chcesz przekazać. eg:

/**
 * A simple interface to wrap up a function of one argument.
 * 
 * @author rcreswick
 *
 */
public interface Function1<S, T> {

   /**
    * Evaluates this function on it's arguments.
    * 
    * @param a The first argument.
    * @return The result.
    */
   public S eval(T a);

}

Następnie, gdy musisz przekazać funkcję, możesz zaimplementować ten interfejs:

List<Integer> result = CollectionUtilities.map(list,
        new Function1<Integer, Integer>() {
           @Override
           public Integer eval(Integer a) {
              return a * a;
           }
        });

Wreszcie, funkcja map używa przekazanego w funkcji 1 w następujący sposób:

   public static <K,R,S,T> Map<K, R> zipWith(Function2<R,S,T> fn, 
         Map<K, S> m1, Map<K, T> m2, Map<K, R> results){
      Set<K> keySet = new HashSet<K>();
      keySet.addAll(m1.keySet());
      keySet.addAll(m2.keySet());

      results.clear();

      for (K key : keySet) {
         results.put(key, fn.eval(m1.get(key), m2.get(key)));
      }
      return results;
   }

Możesz często używać Runnable zamiast własnego interfejsu, jeśli nie musisz przekazywać parametrów, lub możesz użyć różnych innych technik, aby param liczyć mniej "stałe", ale zwykle jest to kompromis z bezpieczeństwem typu. (Możesz też nadpisać konstruktor, aby obiekt funkcji przeszedł w ten sposób w params.. istnieje wiele podejść, a niektóre działają lepiej w pewnych okolicznościach.)

 24
Author: rcreswick,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-23 17:37:15

Odniesienia do metody za pomocą operatora ::

Można używać odniesień do metod w argumentach metod, gdzie metoda akceptuje interfejs funkcjonalny . Interfejs funkcjonalny to każdy interfejs, który zawiera tylko jedną abstrakcyjną metodę. (Interfejs funkcjonalny może zawierać jedną lub więcej domyślnych metod lub metod statycznych.)

IntBinaryOperator jest funkcjonalnym interfejsem. Jego abstrakcyjna metoda, applyAsInt, przyjmuje dwa int s jako swoje parametry i zwraca int. Math.max przyjmuje również dwa int s i zwraca int. W tym przykładzie A.method(Math::max); sprawia, że parameter.applyAsInt wysyła swoje dwie wartości wejściowe do Math.max i zwraca wynik tego Math.max.

import java.util.function.IntBinaryOperator;

class A {
    static void method(IntBinaryOperator parameter) {
        int i = parameter.applyAsInt(7315, 89163);
        System.out.println(i);
    }
}
import java.lang.Math;

class B {
    public static void main(String[] args) {
        A.method(Math::max);
    }
}

Ogólnie można użyć:

method1(Class1::method2);

Zamiast:

method1((arg1, arg2) -> Class1.method2(arg1, arg2));

Co jest skrótem od:

method1(new Interface1() {
    int method1(int arg1, int arg2) {
        return Class1.method2(arg1, agr2);
    }
});

Aby uzyskać więcej informacji, zobacz :: (Double colon) operator w Java 8 i Specyfikacja języka Java §15.13.

 18
Author: The Guy with The Hat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:10:06

Można też to zrobić (co w niektórych rzadko okazje mają sens). Problem (i to jest duży problem) polega na tym, że tracisz wszystkie typy korzystania z klasy / interfejsu i musisz poradzić sobie z przypadkiem, w którym metoda nie istnieje.

Ma tę "zaletę", że można ignorować ograniczenia dostępu i wywoływać metody prywatne (Nie pokazane w przykładzie, ale można wywoływać metody, na które kompilator normalnie nie pozwala).

Ponownie, jest to rzadki przypadek, że ma to sens, ale w tych przypadkach jest to miłe narzędzie.

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

class Main
{
    public static void main(final String[] argv)
        throws NoSuchMethodException,
               IllegalAccessException,
               IllegalArgumentException,
               InvocationTargetException
    {
        final String methodName;
        final Method method;
        final Main   main;

        main = new Main();

        if(argv.length == 0)
        {
            methodName = "foo";
        }
        else
        {
            methodName = "bar";
        }

        method = Main.class.getDeclaredMethod(methodName, int.class);

        main.car(method, 42);
    }

    private void foo(final int x)
    {
        System.out.println("foo: " + x);
    }

    private void bar(final int x)
    {
        System.out.println("bar: " + x);
    }

    private void car(final Method method,
                     final int    val)
        throws IllegalAccessException,
               IllegalArgumentException,
               InvocationTargetException
    {
        method.invoke(this, val);
    }
}
 15
Author: TofuBeer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-26 21:39:48

Jeśli masz tylko jedną linię, która jest inna, możesz dodać parametr, taki jak flag i instrukcję if (flag), która wywołuje jedną linię lub drugą.

 13
Author: Peter Lawrey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-26 21:56:05

Możesz być również zainteresowany, aby usłyszeć o pracy w Java 7 obejmującej zamknięcia:

Jaki jest obecny stan zamknięć w Javie?

Http://gafter.blogspot.com/2006/08/closures-for-java.html
http://tech.puredanger.com/java7/#closures

 12
Author: Dave L.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:10:06

Nowe interfejsy funkcjonalne Java 8 i metody odwołują się do metody za pomocą operatora ::.

Java 8 jest w stanie utrzymywać odniesienia do metod (MyClass:: new) za pomocą wskaźników" @ Functional Interface". Nie ma potrzeby stosowania tej samej nazwy metody, wymagany jest tylko ten sam podpis metody.

Przykład:

@FunctionalInterface
interface CallbackHandler{
    public void onClick();
}

public class MyClass{
    public void doClick1(){System.out.println("doClick1");;}
    public void doClick2(){System.out.println("doClick2");}
    public CallbackHandler mClickListener = this::doClick;

    public static void main(String[] args) {
        MyClass myObjectInstance = new MyClass();
        CallbackHandler pointer = myObjectInstance::doClick1;
        Runnable pointer2 = myObjectInstance::doClick2;
        pointer.onClick();
        pointer2.run();
    }
}
Co my tu mamy?
  1. Functional Interface - jest to interfejs, z adnotacją lub nie @ functional interface , która zawiera tylko jedną deklarację metody.
  2. odniesienia do metod - to tylko specjalna składnia, wygląda tak, objectInstance:: methodName , nic więcej nic mniej.
  3. przykład użycia - tylko operator przypisania, a następnie wywołanie metody interfejsu.

POWINIENEŚ UŻYWAĆ FUNKCJONALNYCH INTERFEJSÓW TYLKO DLA SŁUCHACZY I TYLKO DO TEGO!

Ponieważ wszystkie inne tego typu Wskaźniki funkcji są naprawdę złe dla czytelności kodu i dla zdolności do zrozumienia. Jednakże, bezpośrednie odniesienia do metod czasami się przydają, na przykład z foreach.

Istnieje kilka predefiniowanych interfejsów funkcjonalnych:

Runnable              -> void run( );
Supplier<T>           -> T get( );
Consumer<T>           -> void accept(T);
Predicate<T>          -> boolean test(T);
UnaryOperator<T>      -> T apply(T);
BinaryOperator<T,U,R> -> R apply(T, U);
Function<T,R>         -> R apply(T);
BiFunction<T,U,R>     -> R apply(T, U);
//... and some more of it ...
Callable<V>           -> V call() throws Exception;
Readable              -> int read(CharBuffer) throws IOException;
AutoCloseable         -> void close() throws Exception;
Iterable<T>           -> Iterator<T> iterator();
Comparable<T>         -> int compareTo(T);
Comparator<T>         -> int compare(T,T);

W przypadku wcześniejszych wersji Javy powinieneś wypróbować Biblioteki Guava, które mają podobną funkcjonalność i składnię, jak wspomniał powyżej Adrian Petrescu.

Dla dodatkowych badań spójrz na Java 8 Cheatsheet

I podziękowania dla faceta w kapeluszu za specyfikacja języka Java §15.13 link.

 11
Author: user3002379,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-18 17:23:29

@ sblundy odpowiedź jest świetna, ale anonimowe klasy wewnętrzne mają dwie małe wady, podstawową jest to, że zwykle nie nadają się do wielokrotnego użytku, a druga to nieporęczna składnia.

Fajne jest to, że jego wzór rozszerza się na pełne klasy bez żadnych zmian w klasie głównej (tej wykonującej obliczenia).

Kiedy tworzysz nową klasę, możesz przekazać parametry do tej klasy, która może działać jako stałe w Twoim równaniu. to:

f(x,y)=x*y

Ale czasami potrzebujesz takiego, który jest:

f(x,y)=x*y*2

I może trzecia to:

f(x,y)=x*y/2

Zamiast tworzyć dwie anonimowe klasy wewnętrzne lub dodawać parametr "passthrough" , możesz utworzyć jedną rzeczywistą klasę, którą tworzysz jako instancję:

InnerFunc f=new InnerFunc(1.0);// for the first
calculateUsing(f);
f=new InnerFunc(2.0);// for the second
calculateUsing(f);
f=new InnerFunc(0.5);// for the third
calculateUsing(f);

Po prostu przechowuje stałą w klasie i używa jej w metodzie określonej w interfejsie.

W rzeczywistości, jeśli wiesz, że twoja funkcja nie będzie przechowywana/ponownie używana, możesz to zrobić:

InnerFunc f=new InnerFunc(1.0);// for the first
calculateUsing(f);
f.setConstant(2.0);
calculateUsing(f);
f.setConstant(0.5);
calculateUsing(f);

Ale niezmienne klasy są bezpieczniejsze. nie mogę wymyślić uzasadnienia, żeby taka klasa była zmienna.

Piszę to tylko dlatego, że marudzę za każdym razem, gdy słyszę anonymous inner class-widziałem dużo zbędnego kodu, który był "wymagany", ponieważ pierwszą rzeczą, którą zrobił programista, było przejście na anonimowość, kiedy powinien był użyć prawdziwej klasy i nigdy nie przemyśleć swojej decyzji.

 9
Author: Bill K,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-05-04 18:44:01

Biblioteki Google Guava, które stają się bardzo popularne, mają generyczną funkcjęi predykat obiekt, który pracowali w wielu częściach swojego API.

 6
Author: Adrian Petrescu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-16 21:32:14

Brzmi jak wzór strategii dla mnie. Zobacz też fluffycat.com Java patterns.

 4
Author: Dennis S,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-25 03:21:47

Jedną z rzeczy, których naprawdę brakuje mi podczas programowania w Javie, są wywołania funkcji. Jedną z sytuacji, w której potrzeba tych ciągle się prezentowała, była rekurencyjna hierarchia przetwarzania, w której chcesz wykonać określoną akcję dla każdego elementu. Jak chodzenie po drzewie katalogów lub przetwarzanie struktury danych. Minimalista we mnie nie znosi konieczności definiowania interfejsu, a następnie implementacji dla każdego konkretnego przypadku.

Pewnego dnia zacząłem się zastanawiać dlaczego nie? Mamy metodę pointers-obiekt metody. Dzięki optymalizacji kompilatorów JIT, refleksyjne wywoływanie naprawdę nie niesie już ogromnej kary za wydajność. Poza tym, powiedzmy, kopiowaniem pliku z jednego miejsca do drugiego, koszt wywołania odbitej metody blednie.

Gdy myślałem o tym więcej, zdałem sobie sprawę, że callback w paradygmacie OOP wymaga powiązania obiektu i metody razem-wprowadź obiekt Callback.

Zobacz moje rozwiązanie oparte na refleksji dla wywołań zwrotnych w Javie . Za darmo do dowolnego użytku.

 4
Author: Lawrence Dol,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-28 03:20:55

OK, ten wątek jest już wystarczająco stary, więc bardzo prawdopodobnie moja odpowiedź nie jest pomocna w pytaniu. Ale ponieważ ten wątek pomógł mi znaleźć moje rozwiązanie, i tak go tutaj umieszczę.

Musiałem użyć zmiennej statycznej metody ze znanym wejściem i znanym wyjściem (zarówno double ). Tak więc, znając pakiet metody i nazwę, mogłem pracować w następujący sposób:

java.lang.reflect.Method Function = Class.forName(String classPath).getMethod(String method, Class[] params);

Dla funkcji, która przyjmuje jedno podwójne jako parametr.

Więc w mojej konkretnej sytuacji initialized it with
java.lang.reflect.Method Function = Class.forName("be.qan.NN.ActivationFunctions").getMethod("sigmoid", double.class);

I przywołał go później w bardziej złożonej sytuacji z

return (java.lang.Double)this.Function.invoke(null, args);

java.lang.Object[] args = new java.lang.Object[] {activity};
someOtherFunction() + 234 + (java.lang.Double)Function.invoke(null, args);

Gdzie aktywność jest dowolną wartością podwójną. Zastanawiam się, czy zrobić to trochę bardziej abstrakcyjnie i uogólnić to, jak SoftwareMonkey zrobił, ale obecnie jestem wystarczająco zadowolony z tego, jak to jest. Trzy linijki kodu, brak klas i interfejsów, nie jest tak źle.

 4
Author: yogibimbi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-09 15:22:11

Aby zrobić to samo bez interfejsów dla tablicy funkcji:

class NameFuncPair
{
    public String name;                // name each func
    void   f(String x) {}              // stub gets overridden
    public NameFuncPair(String myName) { this.name = myName; }
}

public class ArrayOfFunctions
{
    public static void main(String[] args)
    {
        final A a = new A();
        final B b = new B();

        NameFuncPair[] fArray = new NameFuncPair[]
        {
            new NameFuncPair("A") { @Override void f(String x) { a.g(x); } },
            new NameFuncPair("B") { @Override void f(String x) { b.h(x); } },
        };

        // Go through the whole func list and run the func named "B"
        for (NameFuncPair fInstance : fArray)
        {
            if (fInstance.name.equals("B"))
            {
                fInstance.f(fInstance.name + "(some args)");
            }
        }
    }
}

class A { void g(String args) { System.out.println(args); } }
class B { void h(String args) { System.out.println(args); } }
 4
Author: vwvan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-17 21:26:44

Zobacz lambdaj

Http://code.google.com/p/lambdaj/

A w szczególności jego nowa funkcja zamknięcia

Http://code.google.com/p/lambdaj/wiki/Closures

I znajdziesz bardzo czytelny sposób definiowania wskaźnika zamknięcia lub funkcji bez tworzenia bezsensownego interfejsu lub używania brzydkich klas wewnętrznych

 3
Author: Mario Fusco,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-12 07:39:12

Wow, dlaczego po prostu nie utworzyć klasy delegata, która nie jest taka trudna, biorąc pod uwagę, że już zrobiłem dla Javy i użyć jej do przekazania w parametrze, gdzie T jest typu return. Przepraszam, ale jako programista C++ / C# w ogóle dopiero uczy się Javy, potrzebuję wskaźników funkcyjnych, ponieważ są one bardzo przydatne. Jeśli znasz jakąś klasę, która zajmuje się informacjami o metodzie, możesz to zrobić. W bibliotekach Javy, które byłyby Javą.lang.zastanów się.metoda.

Jeśli zawsze używasz interfejsu, zawsze musisz zaimplementuj to. W eventhandling naprawdę nie ma lepszego sposobu na rejestrowanie/wyrejestrowanie z listy programów obsługi, ale dla delegatów, w których musisz przekazać funkcje, a nie Typ wartości, dzięki czemu Klasa delegata do obsługi GO dla zdeklasowania interfejsu.

 3
Author: Robert,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-02 04:11:04

Żadna z odpowiedzi Java 8 nie dała pełnego, spójnego przykładu, więc nadchodzi.

Zadeklaruj metodę, która akceptuje "wskaźnik funkcji" w następujący sposób:

void doCalculation(Function<Integer, String> calculation, int parameter) {
    final String result = calculation.apply(parameter);
}

Wywołanie funkcji poprzez podanie wyrażenia lambda:

doCalculation((i) -> i.toString(), 2);
 2
Author: mrts,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-14 19:31:43

Jeśli ktoś ma problemy z przekazaniem funkcji, która wymaga jednego zestawu parametrów do zdefiniowania swojego zachowania, ale innego zestawu parametrów do wykonania, jak Scheme ' s:

(define (function scalar1 scalar2)
  (lambda (x) (* x scalar1 scalar2)))

Zobacz Pass Function with Parameter-Defined Behavior in Java

 1
Author: Scott Emmons,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-10 23:02:32

Od Java8 można używać lambda, które również posiadają biblioteki w oficjalnym API SE 8.

Sposób użycia: Musisz użyć interfejsu tylko z jedną abstrakcyjną metodą. Utwórz jego instancję (możesz chcieć użyć tej, którą java SE 8 już dostarczyła) w następujący sposób:

Function<InputType, OutputType> functionname = (inputvariablename) {
... 
return outputinstance;
}

Więcej informacji znajduje się w dokumentacji: https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html

 1
Author: Alex,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-10 13:44:37

Przed Javą 8, najbliższym substytutem funkcji-wskaźnika była klasa anonimowa. Na przykład:

Collections.sort(list, new Comparator<CustomClass>(){
    public int compare(CustomClass a, CustomClass b)
    {
        // Logic to compare objects of class CustomClass which returns int as per contract.
    }
});

Ale teraz w Javie 8 mamy bardzo zgrabną alternatywę znaną jako wyrażenie lambda , które może być używane jako:

list.sort((a, b) ->  { a.isBiggerThan(b) } );

Gdzie isBiggerThan jest metodą w CustomClass. Możemy również użyć referencji metody tutaj:

list.sort(MyClass::isBiggerThan);
 1
Author: akhil_mittal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-22 09:01:45

Projekt open source safety-mirror uogólnia niektóre z wyżej wymienionych rozwiązań do biblioteki, która dodaje funkcje, delegacje i zdarzenia do Javy.

Zobacz README, lub ta odpowiedź stoskoverflow , aby uzyskać ściągawki funkcji.

Jeśli chodzi o funkcje, biblioteka wprowadza zabawny interfejs i niektóre pod-interfejsy, które (wraz z generykami) tworzą płynne API do używania metod jako typów.

Fun.With0Params<String> myFunctionField = "   hello world   "::trim;`  
Fun.With2Params<Boolean, Object, Object> equals = Objects::equals;`  
    
public void foo(Fun.With1ParamAndVoid<String> printer) throws Exception {
    printer.invoke("hello world);
}  

public void test(){
    foo(System.out::println);
}  

Notice:

  1. że musisz wybierz pod-interfejs, który pasuje do liczby parametrów sygnatury, którą kierujesz. Fx, jeśli ma jeden parametr, wybierz Fun.With1Param.
  2. że Generyki są używane do definiowania A) Typu powrotu i B) parametrów sygnatury.

Zauważ również, że sygnatura odwołania do metody przekazywana do wywołania metody foo () musi być zgodna z Fun zdefiniowaną przez metodę Foo. Jeśli tak się nie stanie, kompilator wyewidencjonuje błąd.

 0
Author: Hervian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-09-07 11:54:54