Risposta breve
No, non è più naturale da usare al posto di Callable
Supplier
in CompletableFuture.supplyAsync
. L'argomento riguarda quasi esclusivamente la semantica, quindi va bene se in seguito ti senti ancora poco convinto.
Long risposta
I/tipi SAM Callable
e Supplier
interfacce funzionali sono praticamente equivalenti in funzione (noir), ma la loro origine e destinazione d'uso differiscono.
Callable
è stato creato come parte del pacchetto java.util.concurrent
. Questo pacchetto è venuto prima dei vasti cambiamenti relativi alle espressioni lambda in Java 8 e si è inizialmente concentrato su una serie di strumenti che hanno aiutato a scrivere codice concorrente, senza deviare molto dal classico modello di multithreading pratico.
Lo scopo principale di Callable
era di astrarre un'azione che può essere eseguita in un thread diverso e che restituisce un risultato. Da Javadoc Callable
s':
L'interfaccia Callable
è simile a Runnable
, dal fatto che entrambi sono progettati per classi le cui istanze sono potenzialmente eseguita da altro thread.
Supplier
è stato creato come parte del pacchetto java.util.function
. Quel pacchetto è venuto come parte integrante delle suddette modifiche in Java 8. Fornisce tipi funzionali comuni che possono essere presi di mira da espressioni lambda e riferimenti al metodo.
Uno di questi tipi è una funzione senza parametri che restituisce un risultato (ad esempio una funzione che fornisce un tipo o una funzione Supplier
).
Quindi perché Supplier
e non Callable
?
CompletableFuture
fa parte di aggiunte al pacchetto java.util.concurrent
ispirate delle citate modifiche in Java 8 e che consentono allo sviluppatore di costruire il suo codice in maniera funzionale, implicitamente parallelizzabile, invece di gestire esplicitamente concorrenza all'interno di esso.
Il suo metodo supplyAsync
ha bisogno di un modo per fornire un risultato di un tipo specifico e più interessato a questo risultato, e non all'azione intrapresa per raggiungere questo risultato. Inoltre, non si preoccupa necessariamente del completamento eccezionale (vedi anche il paragrafo e il ... seguente).
Tuttavia, se viene utilizzato per Runnable
senza parametri, senza risultato interfaccia funzionale, non deve essere usato per Callable
senza parametri, interfaccia funzionale unico risultato?
Non necessariamente.
Un'astrazione per una funzione che non ha un parametro e non restituisce un risultato (e quindi opera interamente tramite effetti collaterali sul contesto esterno) non è stata inclusa in java.util.function
. Ciò significa che (un po 'fastidiosamente) Runnable
viene utilizzato ovunque sia necessaria un'interfaccia funzionale di questo tipo.
E il Exception
controllato che può essere lanciato da Callable.call()
?
È un piccolo segno della differenza semantica prevista tra Callable
e Supplier
.
A Callable
è un'azione che può essere eseguita in un altro thread e che consente di controllare i suoi effetti collaterali come risultato della sua esecuzione. Se tutto va bene, si ottiene un risultato di un tipo specifico, ma poiché possono sorgere situazioni eccezionali durante l'esecuzione di alcune azioni (specialmente nel contesto multithread), è possibile anche definire e gestire tali situazioni eccezionali.
A Supplier
d'altra parte è una funzione su cui ci si basa per fornire oggetti di qualche tipo. Le situazioni eccezionali non devono essere necessariamente considerate responsabilità dell'utente diretto di Supplier
. Questo perché:
- ... interfacce funzionali sono spesso utilizzati per la definizione di una fase specifica in un processo a più fasi per la creazione o la mutazione dei dati e la manipolazione
Exception
s può essere una fase separata, nel caso in cui si cura
- ... in modo esplicito la gestione
Exception
s riduce in modo significativo i poteri espressivi di interfacce funzionali, le espressioni lambda e il metodo fa riferimento
perché avevano appena di essere diverso da C#, che è genericamente chiamato 'Azione <>' e ' Interfacce <> che fanno lo stesso lavoro ma senza confondere il programmatore. E così hanno proliferato interfacce funzionali per metodi con le stesse firme ma nomi diversi. Probabilmente pensavano che avrebbe aiutato il programmatore dandogli un modello mentale con cui lavorare, ma non lo è: è solo un PITA minore. – davidbak