Ich spiele mit den neuen Lambda-Funktionen in Java 8 und habe festgestellt, dass die von Java 8 angebotenen Methoden wirklich nützlich sind. Ich frage mich jedoch, ob es eine gute Möglichkeit gibt, das folgende Szenario zu umgehen. Angenommen, Sie haben einen Objektpool-Wrapper, für den eine Art Factory erforderlich ist, um den Objektpool zu füllen, z. B. (mit 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);
}
}
Nach der Umwandlung der Funktionsschnittstelle in einen Lambda-Ausdruck sieht der obige Code folgendermaßen aus:
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);
}
}
Nicht so schlimm, aber die aktivierte Ausnahme java.sql.SQLException
erfordert einen try
/ catch
Block innerhalb des Lambda. In meiner Firma verwenden wir lange Zeit zwei Schnittstellen:
IOut<T>
das ist ein Äquivalent zujava.lang.functions.Factory
;- und eine spezielle Schnittstelle für die Fälle, in denen normalerweise die Weitergabe geprüfter Ausnahmen erforderlich ist :
interface IUnsafeOut<T, E extends Throwable> { T out() throws E; }
.
Beide IOut<T>
und IUnsafeOut<T>
sollen während der Migration auf Java 8 entfernt werden, es gibt jedoch keine genaue Übereinstimmung für IUnsafeOut<T, E>
. Wenn die Lambda-Ausdrücke mit geprüften Ausnahmen umgehen könnten, als wären sie nicht markiert, könnte es möglich sein, im obigen Konstruktor einfach Folgendes zu verwenden:
super(() -> DriverManager.getConnection(url), maxConnections);
Das sieht viel sauberer aus. Ich sehe, dass ich die Superklasse umschreiben kann ObjectPool
, um unsere zu akzeptieren IUnsafeOut<T>
, aber soweit ich weiß, ist Java 8 noch nicht fertig, daher könnte es einige Änderungen geben wie:
- etwas ähnliches implementieren wie
IUnsafeOut<T, E>
? (Um ehrlich zu sein, halte ich das für schmutzig - das Thema muss wählen, was akzeptiert werden soll: entwederFactory
oder "unsichere Fabrik", die keine kompatiblen Methodensignaturen haben kann) - einfach geprüfte Ausnahmen in Lambdas ignorieren, also keine Notwendigkeit in
IUnsafeOut<T, E>
Ersatz? (Warum nicht? zB eine weitere wichtige Änderung: OpenJDK, das ich verwende,javac
erfordert jetzt nicht, dass Variablen und Parameter deklariert werdenfinal
, um in einer anonymen Klasse [Funktionsschnittstelle] oder einem Lambda-Ausdruck erfasst zu werden.)
Die Frage ist also im Allgemeinen: Gibt es eine Möglichkeit, geprüfte Ausnahmen in Lambdas zu umgehen, oder ist dies in Zukunft geplant, bis Java 8 endgültig veröffentlicht wird?
Update 1
Hm-mm, soweit ich weiß, was wir derzeit haben, scheint es im Moment keinen Weg zu geben, obwohl der Artikel, auf den verwiesen wird, aus dem Jahr 2010 stammt: Brian Goetz erklärt die Ausnahmetransparenz in Java . Wenn sich in Java 8 nicht viel geändert hat, kann dies als Antwort angesehen werden. Auch Brian sagt, dass interface ExceptionalCallable<V, E extends Exception>
(was ich IUnsafeOut<T, E extends Throwable>
aus unserem Code-Erbe erwähnt habe) so ziemlich nutzlos ist, und ich stimme ihm zu.
Vermisse ich noch etwas anderes?