12

有人可以向我解释一下,
为什么将非静态方法引用传递给方法File::isHidden是可以的,
但是将方法引用传递给非静态方法MyCass::mymethod- 给我一个 “不能对非静态方法进行静态引用”

public static void main(String[] args) {
    File[] files = new File("C:").listFiles(File::isHidden); // OK
    test(MyCass::mymethod); // Cannot make a static reference to the non-static method
}

static interface FunctionalInterface{
    boolean function(String file);
}

class MyCass{
    boolean mymethod(String input){
        return true;
    }
}

// HELPER
public static void test(FunctionalInterface functionalInterface){}
4

3 回答 3

10

对非静态方法的方法引用需要一个实例来操作。

listFiles方法的情况下,参数是FileFilterwith accept(File file)。当你对一个实例(参数)进行操作时,你可以参考它的实例方法:

listFiles(File::isHidden)

这是简写

listFiles(f -> f.isHidden())

现在为什么不能使用test(MyCass::mymethod)?因为您根本没有MyCass要操作的实例。

但是,您可以创建一个实例,然后将方法引用传递给您的实例方法:

MyCass myCass = new MyCass(); // the instance
test(myCass::mymethod); // pass a non-static method reference

或者

test(new MyCass()::mymethod);

编辑:MyCass需要声明为静态(static class MyCass)才能从主方法访问。

于 2015-09-16T22:31:41.143 回答
1

正如 peter-walser 指出的那样,因为MyCass::mymethod是实例方法,它需要将实例转换为Function实例。

你的static接口声明前面只是使它成为一个静态接口,它并没有把每个方法都变成一个静态的。

一个可能的解决方案是将类中的方法声明为静态的:

class MyCass{
   static boolean mymethod(String input){
       return true;
   }
}

为了更好地理解它是如何工作的,您可以考虑与方法引用等效的代码MyCass::mymethod(假设上述修改的声明MyClass):

new FunctionalInterface{
  boolean function(String file){
    return MyClass.mymethod(file);
  }
}

您的原始代码将尝试转换为:

new FunctionalInterface{
  boolean function(String file){
    return _missing_object_.mymethod(); # mymethod is not static
  }
}

另一种可能性是使用 aBiFunction 而不是你的FunctionalInterface. 在这种情况下,第一个参数apply是对象,第二个参数是mymethod

于 2015-09-17T10:17:04.117 回答
0

简短的回答:

您正在尝试通过该类访问静态方法。

test(MyCass::mymethod); // Cannot make a static reference to the non-static method

是相同的

test(v -> MyCass.mymethod(v)); // static access

解决方案

使方法静态

class MyCass {
  static boolean mymethod(String input) {
    return true;
  }
}

或者使用对象作为参考

public static void main(String[] args) {
  MyCass myCass = new MyCass();
  test(myCass::mymethod);
}
于 2019-05-24T16:21:42.613 回答