Java 8: Обязательная проверка проверенных исключений в лямбда-выражениях. Почему обязательно, а не необязательно?
Я поигрался с новыми лямбда-функциями в Java 8 и обнаружил, что практики, предлагаемые Java 8, действительно полезны. Однако я'Мне интересно, есть лихорошо способ обойти по следующему сценарию. Предположим, у вас есть оболочка пула объектов, которая требует какой-то фабрики для заполнения пула объектов, например (используяjava.lang.functions.Factory
):
public class JdbcConnectionPool extends ObjectPool {
public ConnectionPool(int maxConnections, String url) {
super(new Factory() {
@Override
public Connection make() {
try {
return DriverManager.getConnection(url);
} catch ( SQLException ex ) {
throw new RuntimeException(ex);
}
}
}, maxConnections);
}
}
После преобразования функционального интерфейса в лямбда-выражение приведенный выше код выглядит так:
public class JdbcConnectionPool extends ObjectPool {
public ConnectionPool(int maxConnections, String url) {
super(() -> {
try {
return DriverManager.getConnection(url);
} catch ( SQLException ex ) {
throw new RuntimeException(ex);
}
}, maxConnections);
}
}
Не так уж и плохо, но проверенное исключениеjava.sql.SQLException
требует /try
catch
блок внутри лямбды. В моей компании мы долгое время используем два интерфейса:
IOut
это эквивалентно;java.lang.functions.Factory
и специальный интерфейс для случаев, когда обычно требуется распространение проверенных исключений:.interface IUnsafeOut { T out() throws E; }
И то и другоеIOut
а такжеIUnsafeOut
должны быть удалены во время перехода на Java 8, однако нет точного соответствияIUnsafeOut
, Если лямбда-выражения могут иметь дело с проверенными исключениями, как если бы они были не проверены, можно было бы использовать просто как в приведенном выше конструкторе:
super(() -> DriverManager.getConnection(url), maxConnections);
Это выглядит намного чище. Я вижу, что могу переписатьObjectPool
супер класс, чтобы принять нашIUnsafeOut
, но, насколько я знаю, Java 8 еще не закончена, поэтому могут быть некоторые изменения, такие как:
IUnsafeOut
? (если честно, считаю грязным - субъект должен выбрать, что принимать: либоFactory
или же "небезопасная фабрика " которые не могут иметь совместимые сигнатуры методов)просто игнорировать проверенные исключения в лямбдах, поэтому нет необходимости вIUnsafeOut
суррогаты? (почему нет? Например, другое важное изменение: OpenJDK, который я использую,javac
теперь не требует, чтобы переменные и параметры были объявлены какfinal
быть захваченным в анонимном классе [функциональном интерфейсе] или лямбда-выражении)Таким образом, вопрос, как правило, заключается в следующем: есть ли способ обойти проверенные исключения в лямбдах или это планируется в будущем, пока Java 8 не будет выпущена окончательно?
Обновление 1
Хм-м-м, насколько я понимаю, что у нас есть в настоящее время, кажется, что сейчас нет пути, несмотря на то, что ссылка на статью датируется 2010 годом:Брайан Гетц объясняет прозрачность исключений в Java, Если в Java 8 ничего не изменилось, это можно считать ответом. Также Брайан говорит, чтоinterface ExceptionalCallable
(что я упомянул какIUnsafeOut
из нашего кода наследие) в значительной степени бесполезно, и я согласен с ним.
Я все еще скучаю по чему-то еще?