Использование ссылки на метод для вызова статических методов

#java #methods #reference #static

#java #методы #ссылка #статический

Вопрос:

Я пытаюсь понять концепцию ссылок на методы. Пробуя разные вызовы, я наткнулся на сценарий, который я не могу полностью понять.

Когда canClim используется без параметра, он может быть передан forEach без проблем, хотя forEach принимает потребителя, который должен принимать параметр? При добавлении параметра в canClim это предотвращает компиляцию?

Однако, когда canClim объявляется как static, он не будет компилироваться без добавления static void canClim(Animal a) в подпись. Разве не должно быть возможно вызвать статический метод без наличия экземпляра класса Animal, потому что он статический?

Спасибо!

 import java.util.*;

class Animal {
    void canClim() {
        System.out.println("I am a climber!");
    }
}

public class MethodReferencer {
    public static void main(String[] args) {
        Animal a = new Animal();
        Animal b = new Animal();
        List<Animal> list = new ArrayList<>(Arrays.asList(a, b));
        list.forEach(Animal::canClim);

    }
}
  

Комментарии:

1. docs.oracle.com/javase/tutorial/java/javaOO/…

2. Вам действительно нужно прочитать о том, как разрешаются ссылки на методы. Было бы слишком широко отвечать здесь.

3. Вы можете думать о методе экземпляра Animal.canClim() как о функции, которая принимает Animal (this) в качестве аргумента: canClim(Animal this) . Когда вы думаете об этом таким образом, становится очевидно, что это действительный потребитель<Animal>. Статические методы, с другой стороны, не имеют this .

4. @JBNizet это имеет смысл, поэтому this предоставляется для принятия потребителем?

5. Вы все правильно поняли…

Ответ №1:

Когда метод нестатичен,

Animal::canClim
эквивалентно
animal -> animal.canClim()
или (animal) -> animal.canClim()

animal В левой части лямбда-выражения является параметром функции-потребителя, а тело находится справа. Итак, да, вы предоставляете там потребителя.

Статические методы ведут себя немного по-другому.
Например, Integer::parseInt стало бы str -> Integer.parseInt(str) .
В основном параметр передается параметру метода. Итак, в статических методах вам необходимо иметь параметр, чтобы иметь возможность использовать ссылки на методы.

Ответ №2:

У Consumer есть метод accept , который принимает аргумент. Статический метод без аргумента не может быть преобразован в Consumer , не так ли?