java - 从 JDK8 升级到 JDK11 后出现奇怪的 java.lang.InstantiationException 和 java.lang.NoSuchMethodException
问题描述
我有以下代码可以在 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);
}
};
}
}
和:
@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);
}
}
此代码在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
有人可以解释一下它对什么不满意以及如何解决它吗?
解决方案
有人可以解释一下它对什么不满意以及如何解决它吗?
用实际替换E
泛型类型Throwable
:
@FunctionalInterface
public interface ThrowingFunction<T, R> {
R apply(T t) throws Throwable;
static <T, R> Function<T, R> unchecked(ThrowingFunction<T, R> function) {
return t -> {
try {
return function.apply(t);
} catch (Throwable e) {
throw new RuntimeException(e);
}
};
}
}
...以下代码在JDK8下构建和工作正常
我认为问题源于与泛型类型不兼容的捕获机制,并且与JLS 8.1.2E
中的语句有关。泛型类和类型参数:
如果泛型类是 Throwable ( §11.1.1)的直接或间接子类,则会出现编译时错误。
由于 Java 虚拟机的 catch 机制仅适用于非泛型类,因此需要此限制。
坦率地说,这是一个猜测,我不知道为什么这可以用 JDK 11 而不是 JDK 8 重现——这很奇怪。
我希望我能帮助你至少解决这个问题。
推荐阅读
- node.js - 使用 Node.js (+ express) 服务器在 OpenWrt 中执行 shell 命令
- reactjs - 如何将道具传递给动态路线?
- html - 我想让滚动条与滚动条拇指一起在 div 中始终可见
- javascript - 在 Javascript 中调用 Flask-Wtform 提交按钮
- php - 根据单击的复选框进行过滤
- java - 我如何比较java中的两个JSONArray?
- javascript - 外部点击在angularjs中不起作用
- neighbours - 如何获取地图中特定点周围的一组最近点?
- vb.net - SQL UPDATE 语句 - 使用 WHERE 的列名无效
- reactjs - 如何防止在 ReactJS 的 URL 中添加字符串?