2016-06-03 4 views
-1

In einer Java 8 Einführung Mini-Buch, sah ich diese Implementierung für die Auflistung versteckte Dateien:Java 8: Wie listen funktionale Interfaces versteckte Dateien auf?

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

und

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

überprüfte ich die Dokumentation und es sieht aus wie listFiles beide FileFilter oder FilenameFilter Implementierung akzeptiert . Beides sind funktionale Schnittstellen.

Aus dem Javadocs:

funktionale Schnittstelle:

Dies ist eine Funktionsschnittstelle und kann daher als das Zuweisungsziel für einen Lambda-Ausdruck oder Methode Referenz verwendet werden.

Meine Fragen: Was in beiden Fällen (der Ausdruck im Vergleich zu dem Verfahren Referenz) geschieht, und wie funktioniert Java anpassen, was ich listFiles schicken?

Was ich meine: Im source code, ich kann keine Angabe, ob listFiles prüft, ob ein Verfahren Referenz- oder Lambda-Ausdruck finden. Ich verstehe, dass Java intern prüft und beide (Lambda oder Methode Ref) zu FileFilter oder FilenameFilter Instanzen, wie durch den Lambda-Ausdruck und wie es sein kann die accept Methode, aber was passiert intern mit File::isHiiden? Ist es mit irgendeiner Art von Klasse umhüllt oder wird es in einen Ausdruck wie den ersten umgewandelt?

Ich weiß, ich bin hier irgendwie verloren, vielleicht verwirrt, aber ich hoffe, dass Sie ziemlich genau verstehen konnten, was meine Fragen sind.

Edit:

ich einige nützliche Anweisungen aus dem docs gefunden (ich ein wenig verändert):

Evaluation eines Expressionsverfahren Referenz von Aufruf der Methode selbst deutlich.

Zur Laufzeit Auswertung eines Expressionsverfahrens Referenz ähnelt Auswertung einer Klasseninstanz Schaffung Ausdruck

die Klasse des gezielten funktionellen Schnittstellentyp mit Eigenschaften

eine neue Instanz einer Klasse implementiert (hängt von der Expression) ist zugewiesen und initialisiert, oder eine bestehende Instanz einer Klasse mit den Eigenschaften unter

der Wert eines Verfahrens Referenzausdruck verwiesen wird, ist ein Verweis auf eine Instanz einer Klasse mit den folgenden Eigenschaften (abhängig von dem Ausdruck)

So zum Beispiel in meinem Fall, wo ich File::isHidden verwende, wird ein Objekt durch eine Klasse erstellt werden, die FileFilter implementiert, FileFilter haben accept Methode, die File Typ-Objekte akzeptiert und isHidden auf diesen File-Typ-Objekten aufruft.

+2

Ihr Quellcode-Link ist Java 6, versuchen Sie das [Java 8] (http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8u40-b25/java/io/File .java /) one –

+0

Die Methode erhält eine Implementierung von 'FileFilter'. Es sieht nicht, wie das eine Lambda/Methode Referenz hinter den Kulissen ist. http://ideone.com/p4Uwo9 - Es sieht genauso aus, es ist nicht identisch, es gibt zum Beispiel keine zusätzliche Klasse, die zur Kompilierzeit erzeugt wird, wie bei realen Implementierungen irgendeiner Schnittstelle. – zapl

+0

Ich würde nicht zu viel Vertrauen in ein Buch setzen Java 8, das java.io.File als Beispiel anstelle von 'Files.newDirectoryStream (mainDirectory, p -> Files.isHidden (p))' verwendet. – VGR

Antwort

2

Wenn Sie JLS 15.27.3 "Typ eines Lambda-Ausdrucks" betrachten, wissen Sie, dass der Lambda-Ausdruck einfach ein Ausdruck ist, der einer Variablen dieser funktionalen Schnittstelle zugewiesen werden kann (hier ist Ihr Lambda ein Ausdruck eines Typs) zuordenbar FileFilter. Dies liegt daran, Ihr Ausdruck (File -> boolean) kongruent mit der FileFilter funktionalen Schnittstelle ist, und nicht die FilenameFilter Schnittstelle.

den zweiten Teil Ihrer Frage zu beantworten, da in der Tat Verpackung in einer Klasse ist, wie in JLS 15.27.4 beschrieben.

Verwandte Themen