英文:
How is method reference syntax working in Java 8
问题
以下是翻译好的内容:
我对 Java 8 中方法引用的工作原理有些困惑。我为筛选文件夹中的隐藏文件编写了以下代码段。它们产生了正确的结果。我不明白代码段的选项 2 中 listFiles 方法的方法签名是如何工作的。
以下是我在 Java 8 文档中找到的内容:
File[] listFiles()
File[] listFiles(FileFilter filter)
File[] listFiles(FilenameFilter filter)
File[] hidden = f.listFiles((p) -> p.isHidden()); // 选项 1 - 函数签名匹配(根据我的理解)
for (int i = 0; i < hidden.length; i++) {
System.out.println(hidden[i]);
}
System.out.println("================================");
File[] hidden1 = f.listFiles(File::isHidden); // 选项 2 - 这个方法调用是如何工作的
for (int i = 0; i < hidden1.length; i++) {
System.out.println(hidden1[i]);
}
英文:
I am having some confusion of how method references work in Java 8. I wrote the following code segment for filtering hidden files in a folder. They are producing correct result. I am not understanding -> how method signature of listFiles method is working for option 2 of this code segment.
This is what I found in Java 8 documentation
File[] listFiles()
File[] listFiles(FileFilter filter)
File[] listFiles(FilenameFilter filter)
<!-- -->
File[] hidden = f.listFiles((p)-> p.isHidden()); //Option 1 - function signature matching (based on my understanding)
for (int i = 0; i < hidden.length; i++) {
System.out.println(hidden[i]);
}
System.out.println("================================");
File[] hidden1 = f.listFiles(File::isHidden); //Option 2 - how this method call is working
for (int i = 0; i < hidden1.length; i++) {
System.out.println(hidden1[i]);
}
答案1
得分: 3
什么是方法引用
您可以将方法引用视为调用现有方法的lambda表达式。
方法引用的种类
方法引用有四种种类:
- 对静态方法的引用:
ContainingClass::staticMethodName
- 对特定对象的实例方法的引用:
containingObject::instanceMethodName
- 对特定类型的任意对象的实例方法的引用:
ContainingType::methodName
- 对构造函数的引用:
ClassName::new
如何理解它?
下面的表达式列出了所有隐藏文件:
f.listFiles(p -> p.isHidden());
这个表达式由实例方法listFiles(FileFilter)
和lambda表达式p -> p.isHidden()
组成,后者不是匿名方法,而是类File
的现有实例方法。
注意,FileFilter
是一个函数式接口,因此可以用作lambda表达式或方法引用的赋值目标。因此,您可以写出表达式f.listFiles(File::isHidden);
附加说明
1)您不需要括号括住p
。为了更好地阅读,建议将(p)
简化为p
。因此,您的lambda表达式将变为p-> p.isHidden()
。
2)您的for循环可以被增强的for循环替代:
for (File value : hidden) {
System.out.println(value);
}
文档:
英文:
What is a method refernce
You can see a method reference as a lambda expression, that call an existing method.
Kinds of method references
There are four kinds of method references:
- Reference to a static method:
ContainingClass::staticMethodName
- Reference to an instance method of a particular object:
containingObject::instanceMethodName
- Reference to an instance method of an arbitrary object of a particular type:
ContainingType::methodName
- Reference to a constructor:
ClassName::new
How to understand it?
The following expression that lists all hidden files:
f.listFiles(p -> p.isHidden());
This expression is composed by the instance method listFiles(FileFilter)
and your lambda expression p -> p.isHidden()
that is not a anonymous method but an existing instance method of the class File
.
Note that FileFilter
is a functional interface and can therefore be used as the assignment target for a lambda expression or method reference. Hence, you can write your expression f.listFiles(File::isHidden);
Side notes
- You don't need the parentheses surrounding the
p
. For a better readibility, I would suggest to replace(p)
with simply ap
. Hence, your lambda expression will becomep-> p.isHidden()
. - Your for loop can be replaced by an enhanced for loop:
for (File value : hidden) {
System.out.println(value);
}
Documentation:
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论