J'ai une question concernant l'inférence de Java 8 en ce qui concerne les lambdas et les signatures d'exception correspondantes.
Si je définis une méthode foo :
public static <T> void foo(Supplier<T> supplier) {
//some logic
...
}
puis j'obtiens la sémantique agréable et concise d'être capable d'écrire foo(() -> getTheT());
dans la plupart des cas, pour un T
. Cependant, dans cet exemple, si mon getTheT
L'opération déclare qu'elle throws Exception
, mon foo
qui prend un fournisseur ne se compile plus : la signature de la méthode Fournisseur pour la méthode get
ne lève pas d'exceptions.
Il semble qu'une façon décente de contourner ce problème serait de surcharger foo pour qu'il accepte l'une ou l'autre option, avec la définition surchargée étant :
public static <T> void foo(ThrowingSupplier<T> supplier) {
//same logic as other one
...
}
où ThrowingSupplier est défini comme suit
public interface ThrowingSupplier<T> {
public T get() throws Exception;
}
De cette façon, nous avons un type de fournisseur qui lève des exceptions et un autre qui ne le fait pas. La syntaxe souhaitée serait quelque chose comme ceci :
foo(() -> operationWhichDoesntThrow()); //Doesn't throw, handled by Supplier
foo(() -> operationWhichThrows()); //Does throw, handled by ThrowingSupplier
Toutefois, cela pose des problèmes en raison de l'ambiguïté du type lambda (probablement incapable de faire la distinction entre Supplier et ThrowingSupplier). En effectuant un cast explicite à la foo((ThrowingSupplier)(() -> operationWhichThrows()));
fonctionnerait, mais il se débarrasserait de la plupart de la concision de la syntaxe souhaitée.
Je suppose que la question sous-jacente est la suivante : si le compilateur Java est capable de résoudre le fait que l'une de mes lambdas est incompatible parce qu'elle lève une exception dans le cas du fournisseur seulement, pourquoi n'est-il pas capable d'utiliser cette même information pour dériver le type de la lambda dans le cas secondaire d'inférence de type ?
Toute information ou ressource que vous pourriez m'indiquer serait également très appréciée, car je ne sais pas trop où chercher pour obtenir plus d'informations sur le sujet.
Merci !