Ссылка на 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:: type? Большое спасибо

Ответ 1

В вашем примере как статический, так и нестатический метод применимы для целевого типа метода фильтра. В этом случае вы не можете использовать ссылку на метод, потому что неоднозначность не может быть разрешена. Подробнее см. В §15.13.1 Заявление о компиляции в описании метода, в частности следующую цитату и приведенные ниже примеры:

Если первый поиск создает статический метод и не применяется нестатический метод [..], то объявление компиляции - результат первого поиска. В противном случае, если статический метод не применим [..], а второй поиск создает нестатический метод, тогда объявление времени компиляции является результатом второго поиска. В противном случае объявления компиляции не существует.

В этом случае вы можете использовать выражение лямбда вместо ссылки на метод:

a.stream().filter(item -> A.is(item));

Вышеприведенное правило относительно поиска статических и нестатических методов является несколько особенным, потому что это не имеет значения, какой метод лучше подходит. Даже если статический метод возьмет объект вместо A, он все же будет неоднозначным. По этой причине я рекомендую в качестве общего руководства: Если в классе есть несколько методов с одинаковым именем (включая методы, унаследованные от базовых классов):

  • Все методы должны иметь одинаковые модификаторы доступа,
  • Все методы должны иметь одинаковые окончательные и абстрактные модификаторы,
  • И все методы должны иметь один и тот же статический модификатор

Ответ 2

Мы не можем использовать не статические методы или неглобальные методы, используя нотацию className:: methodName. Если вы хотите использовать методы определенного класса, вы должны иметь экземпляр класса.

So if you want to access is() method then you can use : 
A a = new A();
a.is();
OR 
(new A()).is();

Спасибо.