Кажется, его немного поздно, но вот мои два цента. Для создания анонимных методов используется выражение lambda . Он ничего не делает, кроме вызова существующего метода, но яснее ссылаюсь на метод непосредственно по его имени. И ссылка метода позволяет нам сделать это с помощью оператора ссылки на метод ::
.
Рассмотрим следующий простой класс, в котором каждый сотрудник имеет имя и оценку.
public class Employee {
private String name;
private String grade;
public Employee(String name, String grade) {
this.name = name;
this.grade = grade;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGrade() {
return grade;
}
public void setGrade(String grade) {
this.grade = grade;
}
}
Предположим, у нас есть список сотрудников, возвращаемых каким-то методом, и мы хотим сортировать сотрудников по их классу. Мы знаем, что мы можем использовать анонимный класс как:
List employeeList = getDummyEmployees();
// Using anonymous class
employeeList.sort(new Comparator() {
@Override
public int compare(Employee e1, Employee e2) {
return e1.getGrade().compareTo(e2.getGrade());
}
});
, где getDummyEmployee () - это некоторый метод как:
private static List getDummyEmployees() {
return Arrays.asList(new Employee("Carrie", "C"),
new Employee("Farhan", "F"),
new Employee("Brian", "B"),
new Employee("Donald", "D"),
new Employee("Adam", "A"),
new Employee("Evan", "E")
);
}
Теперь мы знаем что Comparator является функциональным интерфейсом. Функциональный интерфейс - это тот, который имеет только один абстрактный метод (хотя он может содержать один или несколько стандартных или статических методов). Поэтому мы можем использовать лямбда-выражение как:
employeeList.sort((e1,e2) -> e1.getGrade().compareTo(e2.getGrade())); // lambda exp
Кажется, все хорошо, но что, если класс Employee
также предоставляет аналогичный метод:
public class Employee {
private String name;
private String grade;
// getter and setter
public static int compareByGrade(Employee e1, Employee e2) {
return e1.grade.compareTo(e2.grade);
}
}
В этом случае, используя имя метода будет более понятным. Следовательно, мы можем напрямую ссылаться на метод, используя ссылку на метод:
employeeList.sort(Employee::compareByGrade); // method reference
В соответствии с docs существует четыре типа ссылок на методы:
+----+-------------------------------------------------------+--------------------------------------+
| | Kind | Example |
+----+-------------------------------------------------------+--------------------------------------+
| 1 | Reference to a static method | ContainingClass::staticMethodName |
+----+-------------------------------------------------------+--------------------------------------+
| 2 |Reference to an instance method of a particular object | containingObject::instanceMethodName |
+----+-------------------------------------------------------+--------------------------------------+
| 3 | Reference to an instance method of an arbitrary object| ContainingType::methodName |
| | of a particular type | |
+----+-------------------------------------------------------+--------------------------------------+
| 4 |Reference to a constructor | ClassName::new |
+------------------------------------------------------------+--------------------------------------+