Java 8:以非静态方式引用静态方法的方法

Aur*_*ere 6 java static java-8 method-reference

我正在研究用于OCP考试的新Stream API,我找到了一些我不太懂的东西.这是我的代码:

void methodOne() {
    this.compare(1, 2); // This works fine.
    Stream.of(1,2,3)
        .sorted(this::compare); // Compilation error.
}

static Integer compare(Integer s1, Integer s2) {
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这里我有一个名为compare的静态方法和一个名为compare的非静态方法.如果我从非静态方法调用compare方法,我会得到一个编译器警告:

应该以静态方式访问TestStream类型的方法compare(Integer,Integer)

如果我在流中使用对该方法的方法引用,则该编译器警告将成为具有相同消息的编译器错误.

我知道为什么我收到警告,但如果我使用方法引用,我不明白为什么这个警告会成为编译错误.我也没有在网上找到任何东西.有人可以向我解释一下吗?

Eug*_*ene 12

通过引用访问静态方法被视为当今AFAIK的设计错误.你甚至可以这样做:

YourClass c = null;
c.compare (...)
Run Code Online (Sandbox Code Playgroud)

这样可以正常工作(尽管有警告).

当设计的java-8功能被更正时,访问静态方法(用于方法引用)的唯一方法是通过类本身:

YourClass::compare
Run Code Online (Sandbox Code Playgroud)

  • 另外,请记住,当`c`为'null`时,`c :: compare`会立即失败,而不是等待实际评估函数.所以这将是另一个点,与通过引用调用`static`方法的旧行为不兼容.但是如果你想要旧的行为,你可以使用`args - > c.compare(args)`... (5认同)
  • 那么,15.13.3.,但是,*首先,如果方法引用表达式以ExpressionName或Primary开头,则计算此子表达式.如果子表达式求值为null,则引发NullPointerException,并且方法引用表达式突然完成* (2认同)

kum*_*ana 6

我知道为什么我收到警告,但如果我是方法参考,我不明白为什么这个警告会成为编译错误.我也没有在网上找到任何东西.有人可以向我解释一下吗?

它应该是两种情况下的编译错误,但早期版本的Java容忍它,因为该语言的设计者不知道更好,现在为了继续兼容,改变它为时已晚.

但是,方法引用是新构造的语言语法.当您使用构造时<object instance>::<method name>,根据定义,您尝试引用的方法不能是静态方法,因为您通过指定要应用的对象实例来访问它,静态方法无法执行.

这次正确地做并且拒绝尝试通过实例访问静态内容的无效构造,不会破坏某人可能已经在某处使用过的语言的任何现有语法,尽管这是不明智的.所以他们这次做得对.不要做无效的事情,编译器应该拒绝它们,在这种情况下它会.

在重载方法的情况下,它也会使参数推断复杂化,一些是静态的,一些是非静态的.但它不会是他们必须要做的第一个推断.