方法参考。无法对非静态方法进行静态引用
Method Reference. Cannot make a static reference to the non-static method
谁能给我解释一下,
为什么将非静态方法引用传递给方法 File::isHidden
没问题,
但是将方法引用传递给非静态方法 MyCass::mymethod
- 给了我一个
"Cannot make a static reference to the non-static method" ?
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){}
对非静态方法的方法引用需要一个实例来操作。
在 listFiles
方法的情况下,参数是 FileFilter
和 accept(File file)
。当你操作一个实例(参数)时,你可以参考它的实例方法:
listFiles(File::isHidden)
这是 shorthand 对应
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
) 才能从 main 方法访问。
正如 peter-walser 指出的那样,由于 MyCass::mymethod
是一个实例方法,因此它需要将实例转换为 Function
实例。
你的接口声明前面的static
只是让它成为一个静态接口,它并没有把每个方法都变成静态的。
一个可能的解决方案是将 class 中的方法声明为静态的:
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
}
}
另一种可能性是使用 BiFunction
而不是你的FunctionalInterface
。在这种情况下,apply
的第一个参数是对象,第二个参数是 mymethod
.
的参数
简答:
您正在尝试通过 class.
访问静态方法
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);
}
谁能给我解释一下,
为什么将非静态方法引用传递给方法 File::isHidden
没问题,
但是将方法引用传递给非静态方法 MyCass::mymethod
- 给了我一个
"Cannot make a static reference to the non-static method" ?
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){}
对非静态方法的方法引用需要一个实例来操作。
在 listFiles
方法的情况下,参数是 FileFilter
和 accept(File file)
。当你操作一个实例(参数)时,你可以参考它的实例方法:
listFiles(File::isHidden)
这是 shorthand 对应
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
) 才能从 main 方法访问。
正如 peter-walser 指出的那样,由于 MyCass::mymethod
是一个实例方法,因此它需要将实例转换为 Function
实例。
你的接口声明前面的static
只是让它成为一个静态接口,它并没有把每个方法都变成静态的。
一个可能的解决方案是将 class 中的方法声明为静态的:
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
}
}
另一种可能性是使用 BiFunction
而不是你的FunctionalInterface
。在这种情况下,apply
的第一个参数是对象,第二个参数是 mymethod
.
简答:
您正在尝试通过 class.
访问静态方法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);
}