13

说我有以下代码

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 类型表示法引用实例方法版本?非常感谢

4

2 回答 2

15

在您的示例中,静态和非静态方法都适用于过滤器方法的目标类型。在这种情况下,您不能使用方法引用,因为无法解决歧义。有关详细信息,请参阅方法参考的 §15.13.1编译时声明,特别是以下引用和以下示例:

如果第一次搜索产生一个静态方法,并且没有适用的非静态方法[..],那么编译时声明就是第一次搜索的结果。否则,如果没有适用的静态方法 [..],并且第二次搜索产生非静态方法,则编译时声明是第二次搜索的结果。否则,没有编译时声明。

在这种情况下,您可以使用 lambda 表达式而不是方法引用:

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

上面关于搜索静态和非静态方法的规则有些特殊,因为哪个方法更适合并不重要。即使静态方法将采用Object而不是A,它仍然是模棱两可的。出于这个原因,我建议作为一般准则:如果一个类中有多个同名的方法(包括从基类继承的方法):

  • 所有方法都应具有相同的访问修饰符,
  • 所有方法都应该有相同的 final 和 abstract 修饰符,
  • 并且所有方法都应该具有相同的静态修饰符
于 2014-04-14T09:00:19.043 回答
-6

我们不能通过使用 className::methodName 表示法来使用非静态方法或非全局方法。如果要使用特定类的方法,则必须具有该类的实例。

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

谢谢。

于 2014-04-14T05:29:44.013 回答