2014-04-14 16 views
10

dire che ho il seguente codiceJava 8 riferimento ad un metodo statico vs. metodo di istanza

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

e in un'altra classe ...

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 

la domanda è come faccio a fare riferimento alla versione del metodo di istanza utilizzando la notazione di tipo A :: is? Grazie mille

+0

intendi come richiamare metodo di istanza se entrambi questi metodi ci sono? –

+2

L'errore del compilatore dice: "il riferimento a is è ambiguo, entrambi i metodi sono (A) in A e method is() in A match". Quindi chiaramente il compilatore non può decidere qui. Scommetto che la scelta migliore è cambiare la notazione in un'espressione lambda per renderla evidente. –

risposta

11

Nell'esempio, sia il metodo statico che il metodo non statico sono applicabili al tipo di destinazione del metodo di filtro. In questo caso, non è possibile utilizzare un riferimento al metodo, poiché l'ambiguità non può essere risolta. Vedere §15.13.1 Compile-Time Declaration of a Method Reference per i dettagli, in particolare il seguente preventivo e gli esempi di seguito:

Se la prima ricerca produce un metodo statico, e nessun metodo non-statico è applicabile [..], allora la compilazione -time declaration è il risultato della prima ricerca. Altrimenti, se non è applicabile alcun metodo statico [..] e la seconda ricerca produce un metodo non statico, la dichiarazione di compilazione è il risultato della seconda ricerca. Altrimenti, non esiste una dichiarazione in fase di compilazione.

In questo caso, è possibile utilizzare un'espressione lambda invece di un riferimento metodo:

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

La regola di cui sopra per quanto riguarda la ricerca di metodi statici e non statici è un po 'speciale, perché doesn Non importa, quale metodo è la soluzione migliore. Anche se il metodo statico prenderebbe un oggetto invece di A, è ancora ambiguo. Per questo motivo, vi consiglio come linea guida generale: se ci sono diversi metodi con lo stesso nome in una classe (compresi i metodi ereditati da classi base):

  • Tutti i metodi devono avere lo stesso modificatori di accesso,
  • tutti i metodi dovrebbero avere gli stessi modificatori finali e astratti,
  • e tutti i metodi dovrebbero avere lo stesso modificatore static
-6

Non possiamo usare metodi statici o metodi non globali usando className :: methodName notation. Se vuoi usare i metodi di una particolare classe devi avere un'istanza della classe.

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

Grazie.

+4

[Si tratta di riferimento al metodo Java-8.] (Http://java8.in/java-8-method-references/) –

Problemi correlati