方法引用语法在Java 8中如何工作

huangapple go评论83阅读模式
英文:

How is method reference syntax working in Java 8

问题

以下是翻译好的内容:

我对 Java 8 中方法引用的工作原理有些困惑。我为筛选文件夹中的隐藏文件编写了以下代码段。它们产生了正确的结果。我不明白代码段的选项 2 中 listFiles 方法的方法签名是如何工作的。

以下是我在 Java 8 文档中找到的内容:

  1. File[] listFiles()
  2. File[] listFiles(FileFilter filter)
  3. 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

  1. File[] listFiles()
  2. File[] listFiles(FileFilter filter)
  3. File[] listFiles(FilenameFilter filter)

<!-- -->

File[] hidden = f.listFiles((p)-&gt; p.isHidden()); //Option 1 - function signature matching (based on my understanding)
for (int i = 0; i &lt; hidden.length; i++) {
	System.out.println(hidden[i]);
}
System.out.println(&quot;================================&quot;);
File[] hidden1 = f.listFiles(File::isHidden); //Option 2 - how this method call is working
for (int i = 0; i &lt; hidden1.length; i++) {
	System.out.println(hidden1[i]);
}

答案1

得分: 3

什么是方法引用

您可以将方法引用视为调用现有方法的lambda表达式。

方法引用的种类

方法引用有四种种类:

  • 对静态方法的引用:ContainingClass::staticMethodName
  • 对特定对象的实例方法的引用:containingObject::instanceMethodName
  • 对特定类型的任意对象的实例方法的引用:ContainingType::methodName
  • 对构造函数的引用:ClassName::new

如何理解它?

下面的表达式列出了所有隐藏文件:
f.listFiles(p -&gt; p.isHidden());

这个表达式由实例方法listFiles(FileFilter)和lambda表达式p -&gt; p.isHidden()组成,后者不是匿名方法,而是类File的现有实例方法。

注意,FileFilter是一个函数式接口,因此可以用作lambda表达式或方法引用的赋值目标。因此,您可以写出表达式f.listFiles(File::isHidden);

附加说明

1)您不需要括号括住p。为了更好地阅读,建议将(p)简化为p。因此,您的lambda表达式将变为p-&gt; p.isHidden()
2)您的for循环可以被增强的for循环替代:

for (File value : hidden) {
   System.out.println(value);
}

文档:

方法引用

FileFilter

英文:

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 -&gt; p.isHidden());

This expression is composed by the instance method listFiles(FileFilter) and your lambda expression p -&gt; 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

  1. You don't need the parentheses surrounding the p. For a better readibility, I would suggest to replace (p) with simply a p. Hence, your lambda expression will become p-&gt; p.isHidden().
  2. Your for loop can be replaced by an enhanced for loop:
for (File value : hidden) {
   System.out.println(value);
}

Documentation:

Method reference

FileFilter

huangapple
  • 本文由 发表于 2020年9月28日 14:00:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/64096712.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定