2014-04-14 6 views
10

sagen, dass ich den folgenden Code habenJava 8 Verweis auf eine statische Methode vs. Instanzmethode

public class A { 
    int x; 
    public boolean is() {return x%2==0;} 
    public static boolean is (A a) {return !a.is();} 
} 

und in einer anderen Klasse ...

List<A> a = ... 
a.stream().filter(b->b.isCool()); 
a.stream().filter(A::is); 
//would be equivalent if the static method is(A a) did not exist 

die Frage ist, wie beziehe ich mich auf die Instanzmethode Version mit der Notation A :: ist Typ? Vielen Dank

+0

Sie bedeuten haben, wie Instanzmethode aufzurufen, wenn beide diese Methoden gibt es? –

+2

Der Compiler-Fehler sagt: "Verweis auf is ist mehrdeutig, beide Methode ist (A) in A und Methode ist() in A-Übereinstimmung". So kann der Compiler hier nicht entscheiden. Ich wette, deine beste Wahl ist es, die Notation in einen Lambda-Ausdruck zu ändern, um es deutlich zu machen. –

Antwort

11

In Ihrem Beispiel sind sowohl die statische als auch die nicht statische Methode für den Zieltyp der Filtermethode anwendbar. In diesem Fall können Sie keine Methodenreferenz verwenden, da die Mehrdeutigkeit nicht aufgelöst werden kann. Siehe §15.13.1 Compile-Time Declaration of a Method Reference für Details, insbesondere das folgende Zitat und die folgenden Beispiele:

Wenn die erste Suche eine statische Methode erzeugt, und keine nicht-statische Methode anwendbar ist [..], dann die Kompilierung -Zeitdeklaration ist das Ergebnis der ersten Suche. Andernfalls, wenn keine statische Methode [..] anwendbar ist und die zweite Suche eine nicht statische Methode erzeugt, ist die Deklaration der Kompilierung das Ergebnis der zweiten Suche. Ansonsten gibt es keine Kompilierzeit-Deklaration.

In diesem Fall können Sie einen Lambda-Ausdruck anstelle eines Verfahrens Referenz verwenden:

a.stream().filter(item -> A.is(item)); 

Die obige Regel in Bezug auf die Suche nach statischen und nicht-statische Methoden ist etwas Besonderes, weil es doesn egal, welche Methode passt besser. Selbst wenn die statische Methode ein Objekt statt A dauern würde, ist es immer noch mehrdeutig. Aus diesem Grund empfehle ich als allgemeine Richtlinie: Wenn es mehrere Methoden mit dem gleichen Namen in einer Klasse sind (einschließlich der Methoden von Basisklassen geerbt):

  • Alle Methoden sollten die gleichen Zugriffsmodifikatoren haben,
  • Alle Methoden sollten die gleichen endgültigen und abstrakte Modifikatoren,
  • und alle Methoden sollten den gleichen statischen Modifikator
-6

Wir können nicht statische Methoden oder nicht-globale Methoden verwenden, indem Sie die Notation className :: methodName verwenden. Wenn Sie Methoden einer bestimmten Klasse verwenden möchten, müssen Sie eine Instanz der Klasse haben.

So if you want to access is() method then you can use : 
A a = new A(); 
a.is(); 
OR 
(new A()).is(); 

Danke.

+4

[Dies ist über Java-8 Method Referenz.] (Http://java8.in/java-8-method-references/) –