JDK 11编译失败,而JDK 8编译正常 [英] Compilation fails for JDK 11 and compiles fine for JDK 8

查看:727
本文介绍了JDK 11编译失败,而JDK 8编译正常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

该代码可以在JDK 8(1.8.0_212)上正常编译,但无法在Oracle jdk和open jdk(aws corretto)上都使用JDK 11(11.0.3)进行编译

The code compiles fine with JDK 8 (1.8.0_212) but fails to compile using JDK 11 (11.0.3) both Oracle jdk and open jdk (aws corretto)

尝试使用javac和Maven(maven版本3.6.1和maven-compiler-plugin插件版本3.8.0)进行编译,它针对JDK 8进行编译,而针对JDK 11则失败.

Tried compiling using javac and with Maven (maven version 3.6.1 and maven-compiler-plugin version 3.8.0) it compiles for JDK 8 and fails for 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

推荐答案

可能是因为对规范进行了细微更新.有关系吗?这样是行不通的.

Because slight updates to the spec say so, probably. Does it matter? It's not going to work like this.

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

There is no real purpose to turning the exception thrown into a parameterized type here. Also, youll make quite the chain of RuntimeException with this code. Try this, instead:

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;
}

现在它将可以正常编译.

and now it'll compile fine.

给读者:不要这样做.处理Java规则(如检查的异常)的正确方法是处理它们.使用黑客来绕开语言的本质只是意味着您的代码是非惯用的(其他阅读您的代码的人不会理解它,并且您将很难阅读其他人的代码.这很糟糕),这往往会与其他库互操作的方式很差,并且本来可以帮助您使用的各种功能现在受到了损害(例如:在这里,您会得到很多因果异常链,这使得读取日志和异常跟踪变得更加困难).此外,远离人迹罕至的地方"会导致有趣的时期,例如用于编译的代码不再编译.

TO THE READER: Don't do this. The correct way to deal with java's rules such as checked exceptions is to deal with them. Using hacks to get around the essence of a language just means your code is non-idiomatic (others who read your code won't get it, and you'll have a hard time reading the code of others. That's bad), tends to interop with other libraries in a bad way, and various features that are supposed to help, now hurt (example: Here you get a LOT of causal exception chains which make the reading of your logs and exception traces more difficult than is needed). Also, being 'off the beaten path' this far leads to fun times such as code that used to compile no longer compiling.

这篇关于JDK 11编译失败,而JDK 8编译正常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆