I'm playing with the new lambda features in Java 8, and found that the practices offered by Java 8 are really useful. However, I'm wondering is there a good way to make a work-around for the following scenario. Suppose you have an object pool wrapper that requires some kind of a factory to fill the object pool, for example (using java.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);
}
}
After transforming the functional interface into lambda expression, the code above becomes like that:
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);
}
}
Not so bad indeed, but the checked exception java.sql.SQLException
requires a try
/catch
block inside the lambda. At my company we use two interfaces for long time:
IOut<T>
that is an equivalent to java.lang.functions.Factory
;interface IUnsafeOut<T, E extends Throwable> { T out() throws E; }
.Both IOut<T>
and IUnsafeOut<T>
are supposed to be removed during migration to Java 8, however there is no exact match for IUnsafeOut<T, E>
. If the lambda expressions could deal with checked exceptions like they were unchecked, it could be possible to use simply like the following in the constructor above:
super(() -> DriverManager.getConnection(url), maxConnections);
That looks much cleaner. I see that I can rewrite the ObjectPool
super class to accept our IUnsafeOut<T>
, but as far as I know, Java 8 is not finished yet, so could be there some changes like:
IUnsafeOut<T, E>
? (to be honest, I consider that dirty - the subject must choose what to accept: either Factory
or "unsafe factory" that cannot have compatible method signatures)IUnsafeOut<T, E>
surrogates? (why not? e.g. another important change: OpenJDK, that I use, javac
now does not require variables and parameters to be declared as final
to be captured in an anonymous class [functional interface] or lambda expression)So the question is generally is: is there a way to bypass checked exceptions in lambdas or is it planned in the future until Java 8 is finally released?
Update 1
Hm-m-m, as far as I understand what we currently have, it seems there is no way at the moment, despite the referenced article is dated from 2010: Brian Goetz explains exception transparency in Java. If nothing changed much in Java 8, this could be considered an answer. Also Brian says that interface ExceptionalCallable<V, E extends Exception>
(what I mentioned as IUnsafeOut<T, E extends Throwable>
out of our code legacy) is pretty much useless, and I agree with him.
Do I still miss something else?
Not sure I really answer your question, but couldn't you simply use something like that?
public final class SupplierUtils {
private SupplierUtils() {
}
public static <T> Supplier<T> wrap(Callable<T> callable) {
return () -> {
try {
return callable.call();
}
catch (RuntimeException e) {
throw e;
}
catch (Exception e) {
throw new RuntimeException(e);
}
};
}
}
public class JdbcConnectionPool extends ObjectPool<Connection> {
public JdbcConnectionPool(int maxConnections, String url) {
super(SupplierUtils.wrap(() -> DriverManager.getConnection(url)), maxConnections);
}
}