У меня есть вопрос относительно вывода Java 8 относительно lambdas и связанных с ними исключений.
Если я определю некоторый метод foo:
public static <T> void foo(Supplier<T> supplier) {
//some logic
...
}
тогда я получаю приятную и лаконичную семантику, заключающуюся в возможности писать foo(() -> getTheT());
в большинстве случаев для данного T
. Однако в этом примере, если моя операция getTheT
объявляет, что она throws Exception
, мой метод foo
, который принимает Поставщик, больше не компилируется: подпись метода поставщика для get
не генерирует исключения.
Кажется, что достойным способом обойти это было бы перегрузить foo, чтобы принять любую опцию, причем перегруженное определение:
public static <T> void foo(ThrowingSupplier<T> supplier) {
//same logic as other one
...
}
где ThrowingSupplier определяется как
public interface ThrowingSupplier<T> {
public T get() throws Exception;
}
Таким образом, у нас есть один тип поставщика, который генерирует исключения, а другой - нет. Желаемый синтаксис будет примерно таким:
foo(() -> operationWhichDoesntThrow()); //Doesn't throw, handled by Supplier
foo(() -> operationWhichThrows()); //Does throw, handled by ThrowingSupplier
Однако это вызывает проблемы из-за двусмысленности типа лямбда (предположительно неспособного разрешить между Поставщиком и ThrowingSupplier). Выполнение явного приведения a la foo((ThrowingSupplier)(() -> operationWhichThrows()));
будет работать, но оно избавится от большей части краткости желаемого синтаксиса.
Я предполагаю, что основной вопрос заключается в следующем: если компилятор Java способен решить тот факт, что один из моих lambdas несовместим из-за того, что он бросает исключение в случае только для поставщика, почему он не может использовать тот же самый информацию для получения типа лямбда во вторичном случае типа-вывода?
Любая информация или ресурсы, которые могли бы мне указать на меня, также будут высоко оценены, поскольку я просто не слишком уверен, где искать дополнительную информацию по этому вопросу.
Спасибо!