题主希望这段代码能够编译通过
public List getClasses() throws ClassNotFoundException {
List classes =
Stream.of("java.lang.Object", "java.lang.Integer", "java.lang.String")
.map(className -> Class.forName(className))
.collect(Collectors.toList());
return classes;
}
image.png
但是lambda表达式中不能有检查异常,必须要try...catch...
public List getClasses() throws ClassNotFoundException {
List classes = Stream.of("java.lang.Object", "java.lang.Integer", "java.lang.String").map(className -> {
try {
return Class.forName(className);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}).collect(Collectors.toList());
return classes;
}
看起来很不优雅呀。
于是有个大神写了LambdaExceptionUtil利用泛型的擦除机制
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
public class LambdaExceptionUtil {
@FunctionalInterface
public interface Consumer_WithExceptions {
void accept(T t) throws E;
}
@FunctionalInterface
public interface BiConsumer_WithExceptions {
void accept(T t, U u) throws E;
}
@FunctionalInterface
public interface Function_WithExceptions {
R apply(T t) throws E;
}
@FunctionalInterface
public interface Supplier_WithExceptions {
T get() throws E;
}
@FunctionalInterface
public interface Runnable_WithExceptions {
void run() throws E;
}
/**
* .forEach(rethrowConsumer(name -> System.out.println(Class.forName(name)))); or .forEach(rethrowConsumer(ClassNameUtil::println));
*/
public static Consumer rethrowConsumer(Consumer_WithExceptions consumer)
throws E {
return t -> {
try {
consumer.accept(t);
} catch (Exception exception) {
throwAsUnchecked(exception);
}
};
}
public static BiConsumer rethrowBiConsumer(
BiConsumer_WithExceptions biConsumer) throws E {
return (t, u) -> {
try {
biConsumer.accept(t, u);
} catch (Exception exception) {
throwAsUnchecked(exception);
}
};
}
/**
* .map(rethrowFunction(name -> Class.forName(name))) or .map(rethrowFunction(Class::forName))
*/
public static Function rethrowFunction(Function_WithExceptions function)
throws E {
return t -> {
try {
return function.apply(t);
} catch (Exception exception) {
throwAsUnchecked(exception);
return null;
}
};
}
/**
* rethrowSupplier(() -> new StringJoiner(new String(new byte[]{77, 97, 114, 107}, "UTF-8"))),
*/
public static Supplier rethrowSupplier(Supplier_WithExceptions function)
throws E {
return () -> {
try {
return function.get();
} catch (Exception exception) {
throwAsUnchecked(exception);
return null;
}
};
}
/**
* uncheck(() -> Class.forName("xxx"));
*/
public static void uncheck(Runnable_WithExceptions t) {
try {
t.run();
} catch (Exception exception) {
throwAsUnchecked(exception);
}
}
/**
* uncheck(() -> Class.forName("xxx"));
*/
public static R uncheck(Supplier_WithExceptions supplier) {
try {
return supplier.get();
} catch (Exception exception) {
throwAsUnchecked(exception);
return null;
}
}
/**
* uncheck(Class::forName, "xxx");
*/
public static R uncheck(Function_WithExceptions function, T t) {
try {
return function.apply(t);
} catch (Exception exception) {
throwAsUnchecked(exception);
return null;
}
}
@SuppressWarnings("unchecked")
private static void throwAsUnchecked(Exception exception) throws E {
throw (E)exception;
}
}
然后就可以这样写了,检查异常不是只能在lambda表达式用`try...catch...``,也能放在方法签名了。
public List getClasses() throws ClassNotFoundException {
List classes =
Stream.of("java.lang.Object", "java.lang.Integer", "java.lang.String")
.map(LambdaExceptionUtil.rethrowFunction(className -> Class.forName(className)))
.collect(Collectors.toList());
return classes;
}