简体   繁体   中英

Java 8 reference to a static method vs. instance method

say I have the following code

public class A {
    int x;
    public boolean is() {return x%2==0;}
    public static boolean is (A a) {return !a.is();}
}

and in another class...

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

the question is how do I refer to the instance method version using the A::is type notation? Thanks a lot

In your example, both the static and the non-static method are applicable for the target type of the filter method. In this case, you can't use a method reference, because the ambiguity can not be resolved. See §15.13.1 Compile-Time Declaration of a Method Reference for details, in particular the following quote and the examples below:

If the first search produces a static method, and no non-static method is applicable [..], then the compile-time declaration is the result of the first search. Otherwise, if no static method is applicable [..], and the second search produces a non-static method, then the compile-time declaration is the result of the second search. Otherwise, there is no compile-time declaration.

In this case, you can use a lambda expression instead of a method reference:

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

The above rule regarding the search for static and non-static methods is somewhat special, because it doesn't matter, which method is the better fit. Even if the static method would take an Object instead of A , it's still ambiguous. For that reason, I recommend as a general guideline: If there are several methods with the same name in a class (including methods inherited from base classes):

  • All methods should have the same access modifiers,
  • All methods should have the same final and abstract modifiers,
  • And all methods should have the same static modifier

We can not use not static methods or non-global methods by using className::methodName notation. If you want to use methods of a particular class you have to have an instance of the class.

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

Thanks.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM