Java 8 ссылка на статический метод против метода экземпляра
Скажи, у меня есть следующий код
public class A {
int x;
public boolean is() {return x%2==0;}
public static boolean is (A a) {return !a.is();}
}
и в другом классе...
List<A> a = ...
a.stream().filter(b->b.isCool());
a.stream().filter(A::is);
//would be equivalent if the static method is(A a) did not exist
Вопрос в том, как обратиться к версии метода экземпляра, используя обозначение типа A::is? большое спасибо
2 ответа
В вашем примере как статический, так и нестатический метод применимы для целевого типа метода фильтра. В этом случае вы не можете использовать ссылку на метод, потому что неоднозначность не может быть решена. См. §15.13.1 Объявление времени компиляции ссылки на метод для деталей, в частности, следующая цитата и примеры ниже:
Если при первом поиске создается статический метод, а нестатический метод не применим [..], тогда объявление времени компиляции является результатом первого поиска. В противном случае, если статический метод не применим [..], а второй поиск создает нестатический метод, то объявление времени компиляции является результатом второго поиска. В противном случае, нет никакого объявления времени компиляции.
В этом случае вы можете использовать лямбда-выражение вместо ссылки на метод:
a.stream().filter(item -> A.is(item));
Приведенное выше правило, касающееся поиска статических и нестатических методов, несколько особенное, потому что не имеет значения, какой метод лучше подходит. Даже если статический метод возьмет Object вместо A, он все равно будет неоднозначным. По этой причине я рекомендую в качестве общего руководства: если в классе есть несколько методов с одинаковыми именами (включая методы, унаследованные от базовых классов):
- Все методы должны иметь одинаковые модификаторы доступа,
- Все методы должны иметь одинаковые конечные и абстрактные модификаторы,
- И все методы должны иметь одинаковый статический модификатор
Мы не можем использовать не статические методы или неглобальные методы, используя нотацию className::methodName. Если вы хотите использовать методы определенного класса, у вас должен быть экземпляр класса.
So if you want to access is() method then you can use :
A a = new A();
a.is();
OR
(new A()).is();
Благодарю.