2015-09-16 2 views
8

Qualcuno può spiegare a me,
perché il superamento di un metodo di riferimento non statico al metodo File::isHidden è ok,
ma passando metodo di riferimento a un metodo non statico MyCass::mymethod - mi dà un "Impossibile creare un riferimento statico al metodo non statico"?Metodo di riferimento. Non è possibile fare un riferimento statico per il metodo non statico

public static void main(String[] args) { 
    File[] files = new File("C:").listFiles(File::isHidden); // OK 
    test(MyCass::mymethod); // Cannot make a static reference to the non-static method 
} 

static interface FunctionalInterface{ 
    boolean function(String file); 
} 

class MyCass{ 
    boolean mymethod(String input){ 
     return true; 
    } 
} 

// HELPER 
public static void test(FunctionalInterface functionalInterface){} 

risposta

8

Metodo riferimenti ai metodi non statici richiedono un'istanza operare.

Nel caso del metodo listFiles, l'argomento è un FileFilter con accept(File file). Come si opera su un'istanza (l'argomento), è possibile fare riferimento ai suoi metodi di istanza:

listFiles(File::isHidden) 

, che è una scorciatoia per

listFiles(f -> f.isHidden()) 

Ora, perché non è possibile utilizzare test(MyCass::mymethod)? Perché semplicemente non hai un'istanza di MyCass su cui operare.

È possibile comunque creare un'istanza, e poi passare un riferimento metodo per il vostro metodo di istanza:

MyCass myCass = new MyCass(); // the instance 
test(myCass::mymethod); // pass a non-static method reference 

o

test(new MyCass()::mymethod); 
+1

Non è possibile istanziare 'MyClass' da un metodo' static' (come 'main') perché è una classe interna _non-static_. Dovresti dichiarare la classe come statica. Sto assumendo che il codice nell'esempio originale sia racchiuso all'interno di una classe. –

1

come Peter-Walser rilevare, dal momento che MyCass::mymethod è un metodo di istanza richiede un'istanza da convertire in un'istanza Function.

Il static di fronte alla vostra dichiarazione di interfaccia rende solo un'interfaccia statica , non trasformare ogni metodo in uno statico.

Una possibile soluzione potrebbe essere quella di dichiarare il metodo all'interno della classe come statica:

class MyCass{ 
    static boolean mymethod(String input){ 
     return true; 
    } 
} 

Per capire meglio come funziona, si può considerare il codice Equivalente al metodo di riferimento MyCass::mymethod che è (assumendo che il sopra dichiarazione modificata del MyClass):

new FunctionalInterface{ 
    boolean function(String file){ 
    return MyClass.mymethod(file); 
    } 
} 

tuo codice originale avrebbe cercato di ordinare-di tradurre in:

new FunctionalInterface{ 
    boolean function(String file){ 
    return _missing_object_.mymethod(); # mymethod is not static 
    } 
} 

Un'altra possibilità è utilizzare uno BiFunction anziché il FunctionalInterface. In tal caso il primo argomento di apply sarebbe l'oggetto e il secondo sarebbe l'argomento mymethod.

+1

Il tuo primo esempio deve essere 'MyClass.mymethod (file)'. Il codice dell'OP sarebbe anche tradotto in questo.Ecco da dove viene l'errore "Impossibile creare un riferimento statico ...". Non c'è riferimento statico nel tuo secondo esempio. – zeroflagL