「01」jdk11优势和jdk选择

Posted JAVA架构日记

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了「01」jdk11优势和jdk选择相关的知识,希望对你有一定的参考价值。

Java8 商用收费

从2019年1月份开始,Oracle JDK 开始对 Java SE 8 之后的版本开始进行商用收费,确切的说是 8u201/202 之后的版本。如果你用 Java 开发的功能如果是用作商业用途的,如果还不想花钱购买的话,能免费使用的最新版本是 8u201/202。当然如果是个人客户端或者个人开发者可以免费试用 Oracle JDK 所有的版本。

Java11 的性能提升

仅通过切换到 Java 11 就有 16% 的改进,这种改进可能是因为 Java 10 中引入了 JEP 307: Parallel Full GC for G1。

详情请见Java 11 究竟比 8 快了多少?看看这个基准测试

从java 8到java 11变化一览

说明:这里面我们不会介绍全部特性,只会列举部分作为开发者最关心的变化。

紧凑型的字符串

从Java 9开始 String 数据承载由 char[] 改为 byte[] 紧凑的字符串,在很多时候只包含Latin-1里的字符,这些字符可节省一半内存。

增强api

1.字符串增强 @since 11

// 判断字符串是否为空白" ".isBlank(); // true// 去除首尾空格" Hello Java11 ".strip(); // "Hello Java11"// 去除尾部空格 " Hello Java11 ".stripTrailing(); // " Hello Java11"// 去除首部空格 " Hello Java11 ".stripLeading(); // "Hello Java11 "// 复制字符串"Java11".repeat(3); // "Java11Java11Java11"// 行数统计"A\nB\nC".lines().count(); // 3

2.集合增强

从Java 9 开始,jdk里面就为集合(List、Set、Map)增加了of和copyOf方法。它们用来创建不可变集合。

  • of() @since 9
  • copyOf() @since 10

示例一:

var list = List.of("Java", "Python", "C"); //不可变集合var copy = List.copyOf(list); //copyOf判断是否是不可变集合类型,如果是直接返回System.out.println(list == copy); // truevar list = new ArrayList<String>(); // 这里返回正常的集合var copy = List.copyOf(list); // 这里返回一个不可变集合System.out.println(list == copy); // false

示例二:

var set = Set.of("Java", "Python", "C");var copy = Set.copyOf(set);System.out.println(set == copy); // truevar set1 = new HashSet<String>();var copy1 = List.copyOf(set1);System.out.println(set1 == copy1); // false

示例三:

var map = Map.of("Java", 1, "Python", 2, "C", 3);var copy = Map.copyOf(map);System.out.println(map == copy); // truevar map1 = new HashMap<String, Integer>();var copy1 = Map.copyOf(map1);System.out.println(map1 == copy1); // false

注意:使用 of 和 copyOf 创建的集合为不可变集合,不能进行添加、删除、替换、排序等操作,不然会报java.lang.UnsupportedOperationException异常,使用Set.of()不能出现重复元素、Map.of()不能出现重复key,否则会报java.lang.IllegalArgumentException。。

3.Stream增强 @since 9

Stream是Java 8 中的特性,在Java 9 中为其新增了4个方法:

3.1 ofNullable(T t)

此方法可以接收null来创建一个空流

// 以前Stream.of(null); //报错// 现在Stream.ofNullable(null);

3.2 takeWhile(Predicate<? super T> predicate)

此方法根据Predicate接口来判断如果为true就 取出 来生成一个新的流,只要碰到false就终止,不管后边的元素是否符合条件。

Stream<Integer> integerStream = Stream.of(6, 10, 11, 15, 20);Stream<Integer> takeWhile = integerStream.takeWhile(t -> t % 2 == 0);takeWhile.forEach(System.out::println); // 6,10

3.3 dropWhile(Predicate<? super T> predicate)

此方法根据Predicate接口来判断如果为true就 丢弃 来生成一个新的流,只要碰到false就终止,不管后边的元素是否符合条件。

Stream<Integer> integerStream = Stream.of(6, 10, 11, 15, 20);Stream<Integer> takeWhile = integerStream.dropWhile(t -> t % 2 == 0);takeWhile.forEach(System.out::println); //11,15,20

3.4 iterate重载

以前使用iterate方法生成无限流需要配合limit进行截断

Stream<Integer> limit = Stream.iterate(1, i -> i + 1).limit(5);limit.forEach(System.out::println); //1,2,3,4,5

现在重载后这个方法增加了个判断参数

Stream<Integer> iterate = Stream.iterate(1, i -> i <= 5, i -> i + 1);iterate.forEach(System.out::println); //1,2,3,4,5

4.Optional增强 @since 9

4.1 stream()

如果为空返回一个空流,如果不为空将Optional的值转成一个流。

//返回Optional值的流Stream<String> stream = Optional.of("Java 11").stream();stream.forEach(System.out::println); // Java 11
//返回空流Stream<Object> stream = Optional.ofNullable(null).stream();stream.forEach(System.out::println); //

4.2 ifPresentOrElse(Consumer<? super T> action, Runnable emptyAction)

个人感觉这个方法就是结合isPresent()对Else的增强,ifPresentOrElse 方法的用途是,如果一个 Optional 包含值,则对其包含的值调用函数 action,即 action.accept(value),这与 ifPresent 一致;与 ifPresent 方法的区别在于,ifPresentOrElse 还有第二个参数 emptyAction —— 如果 Optional 不包含值,那么 ifPresentOrElse 便会调用 emptyAction,即 emptyAction.run()。

Optional<Integer> optional = Optional.of(1);optional.ifPresentOrElse( x -> System.out.println("Value: " + x),() ->System.out.println("Not Present.")); //Value: 1
optional = Optional.empty();optional.ifPresentOrElse( x -> System.out.println("Value: " + x),() ->System.out.println("Not Present.")); //Not Present.

4.3 or(Supplier<? extends Optional<? extends T>> supplier)

Optional<String> optional1 = Optional.of("Java");Supplier<Optional<String>> supplierString = () -> Optional.of("Not Present");optional1 = optional1.or( supplierString);optional1.ifPresent( x -> System.out.println("Value: " + x)); //Value: Javaoptional1 = Optional.empty();optional1 = optional1.or( supplierString);optional1.ifPresent( x -> System.out.println("Value: " + x)); //Value: Not Present

5.InputStream增强 @since 9

String lxs = "java";try (var inputStream = new ByteArrayInputStream(lxs.getBytes()); var outputStream = new ByteArrayOutputStream()) { inputStream.transferTo(outputStream); System.out.println(outputStream); //java}

HTTP Client API

api支持同步和异步两种方式,下面是两种方式的示例:

var request = HttpRequest.newBuilder() .uri(URI.create("https://www.baidu.com/")) .build();var client = HttpClient.newHttpClient();// 同步HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());System.out.println(response.body());// 异步CompletableFuture<HttpResponse<String>> sendAsync = client.sendAsync(request, HttpResponse.BodyHandlers.ofString());//这里会阻塞HttpResponse<String> response1 = sendAsync.get();System.out.println(response1.body());

移除内容

  • com.sun.awt.AWTUtilities。
  • sun.misc.Unsafe.defineClass 使用java.lang.invoke.MethodHandles.Lookup.defineClass来替代。
  • Thread.destroy() 以及 Thread.stop(Throwable) 方法。
  • sun.nio.ch.disableSystemWideOverlappingFileLockCheck 属性。
  • sun.locale.formatasdefault 属性。
  • jdk snmp 模块。
  • javafx,openjdk 是从java10版本就移除了,oracle java10还尚未移除javafx ,而java11版本将javafx也移除了。
  • Java Mission Control,从JDK中移除之后,需要自己单独下载。
  • Root Certificates :Baltimore Cybertrust Code Signing CA,SECOM ,AOL and Swisscom。
  • 在java11中将java9标记废弃的Java EE及CORBA模块移除掉。

完全支持Linux容器(包括docker)

许多运行在Java虚拟机中的应用程序(包括Apache Spark和Kafka等数据服务以及传统的企业应用程序)都可以在Docker容器中运行。但是在Docker容器中运行Java应用程序一直存在一个问题,那就是在容器中运行JVM程序在设置内存大小和CPU使用率后,会导致应用程序的性能下降。这是因为Java应用程序没有意识到它正在容器中运行。随着Java 10的发布,这个问题总算得以解决,JVM现在可以识别由容器控制组(cgroups)设置的约束。可以在容器中使用内存和CPU约束来直接管理Java应用程序,其中包括:

  • 遵守容器中设置的内存限制
  • 在容器中设置可用的CPU
  • 在容器中设置CPU约束

JDK推荐

由于 Java 11 开始,Oracle 提供的是付费支持的商业版本。笔者在这更加推荐使用亚马逊的 Corretto,Corretto 采用 GPL 协议。

Corretto的长期支持(LTS)包括Corretto 8的性能增强和安全更新,至少在2023年6月之前免费提供。更新计划每季度发布一次。

亚马逊将为Corretto 11提供LTS的季度更新,至少持续到2024年8月。

声明

本系列文章由微服务核心组件mica作者如梦技术整理撰写, 如有参考或者转载,请保留原作者和注明出处。

专栏目录

  1. 「是时候升级java11了」jdk11优势和jdk选择
  2. 「是时候升级java11了」升级jdk11踩坑记
  3. 「是时候升级java11了」虚拟机Jvm参数设置
  4. 「是时候升级java11了」微服务内http2通信之http2 Clear Text(h2c)
  5. 「是时候升级java11了」微服务内h2c通信的阻碍和问题解决


以上是关于「01」jdk11优势和jdk选择的主要内容,如果未能解决你的问题,请参考以下文章

jdk11和jdk1.8区别

jdk19版本spring用啥版本

怎么根据自己电脑下载合适jdk,下哪个版本最合适?

有效证书上的 JDK 11 SSL 错误(在以前的版本中工作)

win10 环境安装 jdk 11.0.2

JDK 11 马上就要来了!JDK 12 还会远吗?