Java 8: Obowiązkowe sprawdzanie wyjątków w wyrażeniach lambda. Dlaczego obowiązkowe, a nie opcjonalne?

Gram z nowymi funkcjami lambda w Javie 8 i odkryłem, że praktyki oferowane przez Javę 8 są naprawdę przydatne. Zastanawiam się jednak, czy istniejedobry sposób na obejście następującego scenariusza. Przypuśćmy, że masz wrapper puli obiektów, który wymaga pewnego rodzaju fabryki, aby wypełnić pulę obiektów, na przykład (używającjava.lang.functions.Factory):

public class JdbcConnectionPool extends ObjectPool<Connection> {

    public ConnectionPool(int maxConnections, String url) {
        super(new Factory<Connection>() {
            @Override
            public Connection make() {
                try {
                    return DriverManager.getConnection(url);
                } catch ( SQLException ex ) {
                    throw new RuntimeException(ex);
                }
            }
        }, maxConnections);
    }

}

Po przekształceniu interfejsu funkcjonalnego w wyrażenie lambda powyższy kod wygląda tak:

public class JdbcConnectionPool extends ObjectPool<Connection> {

    public ConnectionPool(int maxConnections, String url) {
        super(() -> {
            try {
                return DriverManager.getConnection(url);
            } catch ( SQLException ex ) {
                throw new RuntimeException(ex);
            }
        }, maxConnections);
    }

}

Nie tak źle, ale sprawdzony wyjątekjava.sql.SQLException wymagatry/catch blok wewnątrz lambda. W mojej firmie używamy dwóch interfejsów przez długi czas:

IOut<T> to jest odpowiednikjava.lang.functions.Factory;oraz specjalny interfejs dla przypadków, które zwykle wymagają propagowania sprawdzonych wyjątków:interface IUnsafeOut<T, E extends Throwable> { T out() throws E; }.

ObieIOut<T> iIUnsafeOut<T> powinny zostać usunięte podczas migracji do Java 8, jednak nie ma dokładnego dopasowaniaIUnsafeOut<T, E>. Jeśli wyrażenia lambda mogłyby poradzić sobie z zaznaczonymi wyjątkami, takimi jak te, które nie były zaznaczone, możliwe byłoby użycie po prostu w powyższym konstruktorze:

super(() -> DriverManager.getConnection(url), maxConnections);

To wygląda na znacznie czystsze. Widzę, że mogę przepisaćObjectPool super klasa, aby zaakceptować nasząIUnsafeOut<T>, ale o ile wiem, Java 8 jeszcze się nie skończyła, więc może być kilka zmian, takich jak:

wdrożenie czegoś podobnegoIUnsafeOut<T, E>? (szczerze mówiąc, uważam to za brudne - podmiot musi wybrać, co zaakceptować: alboFactory lub „niebezpieczna fabryka”, która nie może mieć zgodnych podpisów metod)po prostu ignorując sprawdzone wyjątki w lambdach, więc nie ma potrzebyIUnsafeOut<T, E> zastępcy? (dlaczego nie? np. inna ważna zmiana: OpenJDK, którego używam,javac teraz nie wymaga deklarowania zmiennych i parametrów jakofinal do przechwycenia w anonimowej klasie [interfejs funkcjonalny] lub wyrażeniu lambda)

Zatem pytanie brzmi ogólnie: czy istnieje sposób na ominięcie sprawdzonych wyjątków w lambdach lub czy jest planowany w przyszłości, aż Java 8 zostanie ostatecznie wydana?

Aktualizacja 1

Hm-m-m, o ile rozumiem, co mamy obecnie, wydaje się, że w tej chwili nie ma sposobu, mimo że wspomniany artykuł pochodzi z 2010 roku:Brian Goetz wyjaśnia przejrzystość wyjątków w Javie. Jeśli w Javie 8 nic się nie zmieniło, można to uznać za odpowiedź. Również Brian tak mówiinterface ExceptionalCallable<V, E extends Exception> (o czym wspomniałem jakoIUnsafeOut<T, E extends Throwable> poza naszym dziedzictwem kodu) jest prawie bezużyteczny i zgadzam się z nim.

Czy wciąż tęsknię za czymś innym?

questionAnswers(8)

yourAnswerToTheQuestion