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();

Благодарю.

Другие вопросы по тегам