Aviel Fedida Aviel Fedida - 6 months ago 16
Java Question

Java 8: How do functional Interfaces list hidden files?

In a Java 8 introduction mini-book, I saw these implementation for listing hidden files:

File[] hiddenFiles = mainDirectory.listFiles(f -> f.isHidden());


and

File[] hiddenFiles = mainDirectory.listFiles(File::isHidden);


I checked the docs and it looks like
listFiles
accepts both
FileFilter
or
FilenameFilter
implementation. Both are functional interfaces.

From the Javadocs:


Functional Interface:

This is a functional interface and can therefore be used as the
assignment target for a lambda expression or method reference.


My questions: What happens in both cases (the expression versus the method reference), and how does Java adjust what I send to
listFiles
?

What I mean: In the source code, I can't find any indication whether
listFiles
checks for a method reference or lambda expression. I understand that Java internally checks and adjust both (lambda or method ref) to become
FileFilter
or
FilenameFilter
instances, as shown by the lambda expression and how it can be the
accept
method, but what happens internally with
File::isHiiden
? Is it wrapped with some kind of class, or is it transformed into expression such as the first case?

I know I'm kind of lost here, maybe confused, but I hope you could understand pretty much what my questions is.

Edit:

I found few useful statements from the docs (I changed a bit):


Evaluation of a method reference expression is distinct from
invocation of the method itself.

At run time, evaluation of a method reference expression is similar to
evaluation of a class instance creation expression

The class implements the targeted functional interface type

A new instance of a class with properties(depends on the expression) is
allocated and initialized, or an existing instance of a class with the
properties below is referenced

The value of a method reference expression is a reference to an
instance of a class with the following properties(depends on the
expression)


So for example in my case, where I use
File::isHidden
, an object will be created by a class that implements
FileFilter
,
FileFilter
have
accept
method that accepts
File
type objects and calls
isHidden
on those
File
type objects.

Answer

If you look at JLS 15.27.3, "Type of a Lambda Expression", you will know that the lambda expression is simply an expression that can be assigned to a variable of that functional interface (here your lambda is an expression of a type assignable to FileFilter. This is because your expression (File -> boolean) is congruent with the FileFilter functional interface, and not the FilenameFilter interface.

To answer the second part of your question, there is in fact wrapping in a class, as described in JLS 15.27.4.