JDK 11 编译失败,JDK 8 编译正常
Compilation fails for JDK 11 and compiles fine for JDK 8
代码使用 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
因为对规范的轻微更新可能是这样说的。有关系吗?它不会像这样工作。
这里把抛出的异常转成参数化类型没有实际意义。此外,您将使用此代码创建完整的 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;
}
现在可以正常编译了。
致READER:不要这样做。 java的规则如checked exceptions的正确处理方式是处理它们。使用 hack 来绕过语言的本质只是意味着你的代码是 non-idiomatic(其他人阅读你的代码不会明白,你将很难阅读别人的代码。那很糟糕),倾向于以一种糟糕的方式与其他库进行互操作,而本应有所帮助的各种功能现在却受到了伤害(例如:这里有很多因果异常链,这使得读取日志和异常跟踪比需要的更加困难) .此外,作为 'off the beaten path' 这么远会带来一些有趣的时间,例如用于编译的代码不再编译。
代码使用 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
因为对规范的轻微更新可能是这样说的。有关系吗?它不会像这样工作。
这里把抛出的异常转成参数化类型没有实际意义。此外,您将使用此代码创建完整的 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;
}
现在可以正常编译了。
致READER:不要这样做。 java的规则如checked exceptions的正确处理方式是处理它们。使用 hack 来绕过语言的本质只是意味着你的代码是 non-idiomatic(其他人阅读你的代码不会明白,你将很难阅读别人的代码。那很糟糕),倾向于以一种糟糕的方式与其他库进行互操作,而本应有所帮助的各种功能现在却受到了伤害(例如:这里有很多因果异常链,这使得读取日志和异常跟踪比需要的更加困难) .此外,作为 'off the beaten path' 这么远会带来一些有趣的时间,例如用于编译的代码不再编译。