【问题标题】:Compilation fails for JDK 11 and compiles fine for JDK 8JDK 11 编译失败,JDK 8 编译正常
【发布时间】:2019-06-26 10:36:10
【问题描述】:

代码使用 JDK 8 (1.8.0_212) 编译良好,但无法使用 JDK 11 (11.0.3) 编译 Oracle jdk 和 open jdk (aws corretto)

尝试使用 javac 和 Maven(maven 版本 3.6.1 和 maven-compiler-plugin 版本 3.8.0)进行编译,它可以针对 JDK 8 进行编译,但针对 JDK 11 会失败。

import java.net.URL;
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.function.Function;
import java.util.stream.Stream;

public class AppDemo {
    public static void main(String[] args) {
        // NO error here
        giveMeStream("http://foo.com").map(wrap(url -> new URL(url)));

        List<String> list = new ArrayList<String>();
        list.add("http://foo.com/, http://bar.com/");
        // error: unreported exception MalformedURLException;
        // must be caught or declared to be thrown
        list.stream().flatMap(
            urls -> Arrays.<String>stream(urls.split(",")).map(wrap(url -> new URL(url)))
        );

        // error: unreported exception MalformedURLException;
        // must be caught or declared to be thrown
        Stream.concat(
            giveMeStream("http://foo.com").map(wrap(url -> new URL(url))),
            giveMeStream("http://bar.com").map(wrap(url -> new URL(url))));

    }


    static Stream<String> giveMeStream(String s) {
        return Arrays.stream(new String[]{s});
    }

    static <T, R, E extends Throwable> Function<T, R>
    wrap(FunException<T, R, E> fn) {
        return t -> {
            try {
                return fn.apply(t);
            } catch (Throwable throwable) {
                throw new RuntimeException(throwable);
            }
        };
    }

    interface FunException<T, R, E extends Throwable> {
        R apply(T t) throws E;
    }
}

错误:

Expected : No compilation error
Actual : compilation error for JDK11
Error message with JDK 11:

s.<String>stream(urls.split(",")).map(wrap(url -> new URL(url)))
                                                               ^
AppDemo.java:24: error: unreported exception MalformedURLException; must be caught or declared to be thrown
            giveMeStream("http://foo.com").map(wrap(url -> new URL(url))),
                                                           ^
AppDemo.java:25: error: unreported exception MalformedURLException; must be caught or declared to be thrown
            giveMeStream("http://bar.com").map(wrap(url -> new URL(url))));
                                                           ^
3 errors

【问题讨论】:

  • 您忘记包含实际错误?
  • 您好,我从错误的文件中发布了代码,如何更新代码?
  • @Fazal 点击帖子底部的编辑(标签下方)
  • @Karthikeyan Vaithilingam 谢谢,我已经编辑了代码,添加了编译错误。
  • 似乎是类型推断问题。使用(String url) -&gt; new URL(url) 解决它。作为旁注,您可以使用Stream.of(s) 代替Arrays.stream(new String[]{s}),这会使giveMeStream 方法过时。所以你可以使用Stream.of("http://foo.com", "http://bar.com").map(wrap(URL::new)) …

标签: java java-8 java-11


【解决方案1】:

可能是因为对规范的轻微更新是这样说的。有关系吗?它不会像这样工作。

在这里将抛出的异常转换为参数化类型并没有真正的目的。此外,您将使用此代码制作完整的RuntimeException 链。试试这个吧:

static <T, R> Function<T, R> wrap(FunException<T, R> fn) {
    return t -> {
        try {
            return fn.apply(t);
        } catch (Error | RuntimeException ex) {
            throw ex;
        } catch (Throwable throwable) {
            throw new RuntimeException("Checked exception in lambda", throwable);
        }
    };
}

interface FunException<T, R> {
    R apply(T t) throws Throwable;
}

现在它可以正常编译了。

致读者:不要这样做。处理检查异常等java的规则的正确方法是处理它们。使用技巧来绕过语言的本质只是意味着您的代码是非惯用的(阅读您的代码的其他人不会理解它,并且您将很难阅读其他人的代码。这很糟糕),往往以一种糟糕的方式与其他库进行互操作,并且应该提供帮助的各种功能现在受到了伤害(例如:这里有很多因果异常链,这使得读取日志和异常跟踪比需要的更困难)。此外,到目前为止,“不走寻常路”会导致有趣的时刻,例如用于编译的代码不再编译。

【讨论】:

  • 这里有多个 catch 块真的有用吗? Throwable wrapper 将始终被调用!只是问
  • @rzwitserloot 感谢您的帮助。我完全同意处理检查异常的建议。
  • 我想你可能错过了@Fazal 的观点。我们要求最小的可重现示例,这就是 Fazal 给我们的。他不是在问如何做某事,而是在问为什么相同的代码在某些地方编译而在其他地方不编译。
  • 这个解决方案与UncheckedIOException 一样惯用,它是专门为处理Stream API 中检查的IOException 而创建的,通过包装它......
  • @Kris 和 Jean-Baptiste Yunes 当然这个额外的子句很有用:现在,任何可以抛出的异常都会被抛出。另一个将包裹它们。有了足够多的 lambda 应用程序,任何异常都将在 RuntimeExceptions 链中深入 8 层。
猜你喜欢
  • 2019-07-21
  • 1970-01-01
  • 1970-01-01
  • 2012-01-03
  • 1970-01-01
  • 2023-03-24
  • 2019-08-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多