Сбой компиляции для JDK 11 и компиляция нормально для JDK 8 - PullRequest
5 голосов
/ 26 июня 2019

Код прекрасно компилируется с 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 version 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

1 Ответ

1 голос
/ 26 июня 2019

Потому что небольшие обновления в спецификации говорят так, наверное. Это имеет значение? Это не сработает.

Нет реальной цели превращать исключение в параметризованный тип здесь. Кроме того, вы сделаете из этого кода цепочку 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, такими как проверенные исключения, состоит в том, чтобы иметь дело с ними. Использование хаков, чтобы обойти суть языка, просто означает, что ваш код не является идиоматическим (другие, которые читают ваш код, не получат его, и вам будет трудно читать код других. Это плохо), имеет тенденцию к плохое взаимодействие с другими библиотеками, и различные функции, которые должны помочь, теперь пострадали (пример: здесь вы получаете МНОГО цепей причинных исключений, которые затрудняют чтение ваших журналов и трассировок исключений, чем это необходимо). Кроме того, «далеко от проторенного пути» это приводит к забавным временам, таким как код, который раньше компилировался, больше не компилируется.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...