Groovy - ВНИМАНИЕ: произошла недопустимая операция доступа с отражением

Обычно можно вызвать метод reduce, используя Math.max(int, int) следующим образом:

reduce(new IntBinaryOperator() {
    int applyAsInt(int left, int right) {
        return Math.max(left, right);
    }
});

Для этого требуется много синтаксиса только для вызова Math.max. Вот тут и появляются лямбда-выражения. Начиная с Java 8 разрешено делать то же самое гораздо короче:

reduce((int left, int right) -> Math.max(left, right));

Как это работает? Компилятор java «обнаруживает», что вы хотите реализовать метод, который принимает два int s и возвращает один int. Это эквивалентно формальным параметрам одного и только метода интерфейса IntBinaryOperator (параметр метода reduce, который вы хотите вызвать). Таким образом, компилятор делает для вас все остальное - он просто предполагает, что вы хотите реализовать IntBinaryOperator.

Но поскольку сам Math.max(int, int) выполняет формальные требования IntBinaryOperator, его можно использовать напрямую. Поскольку Java 7 не имеет синтаксиса, который позволяет передавать сам метод как аргумент (вы можете передавать только результаты метода, но никогда не ссылаетесь на методы), синтаксис :: был введен в Java 8 для ссылок на методы:

reduce(Math::max);

Обратите внимание, что это будет интерпретироваться компилятором, а не JVM во время выполнения! Хотя он создает разные байт-коды для всех трех фрагментов кода, они семантически равны, поэтому последние два можно считать короткими (и, вероятно, более эффективными) версиями реализации IntBinaryOperator выше!

(См. также Перевод лямбда-выражений )

18
задан Here_2_learn 22 December 2017 в 04:20
поделиться