2015-07-15 10 views
11

il seguente codice:Perché ci sono 2 frame stack per un richiamo lambda?

public static void main(String[] args) { 
    Collections.singleton(1).stream().forEach(i -> new Exception().printStackTrace()); 
} 

stampe:

java.lang.Exception 
    at PrintLambdaStackTrace.lambda$main$0(PrintLambdaStackTrace.java:6) 
    at PrintLambdaStackTrace$$Lambda$1/1831932724.accept(Unknown Source) 
    at java.util.Collections$2.tryAdvance(Collections.java:4717) 
    at java.util.Collections$2.forEachRemaining(Collections.java:4725) 
    at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:580) 
    at PrintLambdaStackTrace.main(PrintLambdaStackTrace.java:6) 

Come è l'invocazione lambda implementato? Perché ci sono 2 frame stack?

+0

Questa è una buona domanda. Guarderò da quando sono interessato alla risposta me stesso. La mia ipotesi è che la JVM crei una classe anonima al momento dell'esecuzione. Uno stack proviene dal metodo utilizzato per creare la classe e il secondo dalla classe stessa. Ma è solo una supposizione. – Sekkuar

+1

Vedere anche http://stackoverflow.com/q/16827262/2711488 – Holger

risposta

7
PrintLambdaStackTrace$$Lambda$1/1831932724.accept(Unknown Source) 

Questa è una classe generata che implementa l'interfaccia richiesta. Il suo metodo accept è solo uno stub, delegante a un metodo che è stato generato in fase di compilazione e aggiunto alla classe PrintLambdaStackTrace. Questa classe viene generata al momento del collegamento lambda (la prima volta che è necessario creare un'istanza lambda).

PrintLambdaStackTrace.lambda$main$0(PrintLambdaStackTrace.java:6) 

Questo è il metodo che implementa effettivamente il comportamento di lambda. Appartiene alla classe PrintLambdaStackTrace.

+1

Non lo chiamerei * inner * class. È solo una classe generata. – Holger

+0

Vedo. E qual è il vantaggio di questo approccio rispetto alla traduzione del lambda in una classe anonima? –

+2

@Bogdan Calmac: il metodo di implementazione risiede nella classe che definisce l'espressione lambda, quindi ha naturalmente accesso alla classe circostante. Inoltre, nessun file di classe aggiuntivo che si trova sul disco/nel file jar ... – Holger

Problemi correlati