我有以下代码可以在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下可以正常构建和运行

我认为问题出在与E通用类型不兼容的捕获机制中,并且与JLS 8.1.2. Generic Classes and Type Parameters中的语句有关:

如果泛型类是Throwable(§11.1.1)的直接或间接子类,则它是编译时错误
由于Java虚拟机的catch机制仅适用于非通用类,因此需要此限制。

坦率地说,这是一个猜测,我不知道为什么这可以用JDK 11再现但不能用JDK 8再现-这很奇怪。
希望我至少可以帮助您解决该问题。

07-24 20:48