car*_*ing 5 java generics lambda exception java-11
我有以下代码可以在 JDK8 下构建并正常工作:
@FunctionalInterface
public interface ThrowingFunction<T, R, E extends Throwable> {
R apply(T t) throws E;
static <T, R, E extends Throwable> Function<T, R> unchecked (ThrowingFunction<T, R, E> function) {
return t -> {
try {
return function.apply(t);
}
catch (Throwable e) {
throw new RuntimeException(e);
}
};
}
}
Run Code Online (Sandbox Code Playgroud)
和:
@Component
public class CronJobDuplicationCheckStrategiesRegistry {
private final Map<String, Set<CronJobDuplicationCheckStrategy>> duplicationStrategies;
CronJobDuplicationCheckStrategiesRegistry(final CronJobsRegistry cronJobsRegistry) {
duplicationStrategies = cronJobsRegistry.get()
.stream()
.collect(Collectors.toMap(
clazz -> clazz.getName(),
ThrowingFunction.unchecked(
clazz -> clazz.getDeclaredConstructor()
.newInstance()
.getDuplicationStrategies())));
}
public Set<CronJobDuplicationCheckStrategy> get(String jobClass) {
return duplicationStrategies.get(jobClass);
}
}
Run Code Online (Sandbox Code Playgroud)
这段代码在JDK11下编译失败,报错如下:
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.3:compile (default-compile) on project cron-api: Compilation failure: Compilation failure:
[ERROR] /java/org/foo/src/main/java/org/foo/jobs/CronJobDuplicationCheckStrategiesRegistry.java:[26,120] unreported exception java.lang.NoSuchMethodException; must be caught or declared to be thrown
[ERROR] /java/org/foo/src/main/java/org/foo/src/main/java/org/foo/cron/jobs/CronJobDuplicationCheckStrategiesRegistry.java:[27,109] unreported exception java.lang.InstantiationException; must be caught or declared to be thrown
Run Code Online (Sandbox Code Playgroud)
有人可以解释一下它不满意的地方以及如何解决吗?
\n\n有人可以解释一下它的不满意之处以及如何解决它吗?
\n
将泛型类型替换E
为实际类型Throwable
:
@FunctionalInterface\npublic interface ThrowingFunction<T, R> {\n R apply(T t) throws Throwable;\n\n static <T, R> Function<T, R> unchecked(ThrowingFunction<T, R> function) {\n return t -> {\n try {\n return function.apply(t);\n } catch (Throwable e) {\n throw new RuntimeException(e);\n }\n };\n }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n\n...以下代码在 JDK8 下构建并运行良好
\n
我认为问题源于捕获机制,该机制与通用类型不兼容E
,并且与 JLS 8.1.2 中的声明有关。通用类和类型参数:
\n\n如果泛型类是 Throwable ( \xc2\xa711.1.1)的直接或间接子类,则这是一个编译时错误。
\n由于 Java 虚拟机的 catch 机制仅适用于非泛型类,因此需要此限制。
\n
坦率地说,这是一个猜测,我不知道为什么这可以在 JDK 11 中重现,但不能在 JDK 8 中重现 - 这很奇怪。
\n我希望我至少能帮助你解决这个问题。
\n