1. JDK版本变迁和各版本新特性
JDK从1995年发布起至今已历经20多年,从JDK1.0升级到JDK17(October 19, 2021),本节先一起回顾一下JDK的版本变迁和各版本的新特性
版本变迁
1995年5月23日,Java语言诞生;
1996年1月,第一个JDK-JDK1.0诞生;
1996年4月,10个最主要的操作系统供应商申明将在其产品中嵌入Java技术;
1996年9月,约8.3万个网页应用了Java技术来制作;
1997年2月18日,JDK1.1发布;
1997年4月2日,JavaOne会议召开,参与者逾一万人,创当时全球同类会议纪录;
1997年9月,JavaDeveloperConnection社区成员超过十万;
1998年2月,JDK1.1被下载超过2,000,000次;
1998年12月8日,Java 2企业平台J2EE发布;
1999年6月,SUN公司发布Java三个版本:标准版(J2SE)、企业版(J2EE)和微型版(J2ME);
2000年5月8日,JDK1.3发布;
2001年6月5日,Nokia宣布到2003年将出售1亿部支持Java的手机;
2001年9月24日,J2EE1.3发布;
2002年2月26日,J2SE1.4发布,此后Java的计算能力有了大幅提升
2004年9月30日,J2SE1.5发布,成为Java语言发展史上的又一里程碑。为了表示该版本的重要性,J2SE1.5更名为Java SE 5.0;有诸多重大新特性;代号:Tiger(里程碑版本)
2006年12月,SUN公司发布JDK6.0;代号: Mustang 此版本持续了5年之久才发布新版本,是最经典的版本。
2009年12月,SUN公司发布Java EE 6;
2010年11月,由于甲骨文对Java社区的不友善,因此Apache扬言将退出JCP;
2011年7月28日,甲骨文发布Java SE 7;
2014年3月18日,甲骨文发表Java SE 8。(重大版本 - LTS)
2017年9月21日,JDK9发布。从JDK9开始固定为每半年一个版本,更新内容相应缩减。
2018年3月21日,JDK10发布。
2018年9月25日,JDK11发布。(长期维护版本 - LTS)
2019年3月19日,JDK12发布。
2019年9月17日,JDK13发布。
2020年3月17日,JDK14发布。
2020年9月15日,JDK15发布。
2021年3月16日,JDK16发布。
2021年9月, JDK17发布。(长期维护版本 - LTS)
版本新特性
对重要版本的新特性做一下说明。
JDK1.2
改进集合框架,如新增HashMap替代旧的HashTable(常用)
开始提供JIT(Just In Time)编译器;
JDK1.3
Dynamic Proxy: 加入了JDK动态代理(常用)
JDK1.4
NIO: 在传统BIO的基础上引入了NIO(Non-Blocking IO)(常用)。
JDK5(2004-09)
里程碑版本,大部分人也是从该版本开始接触Java。引入了很多意义深远的特性,如下:
1)自动拆箱/装箱(Auto Inbox/Outbox)(常用)
2)枚举(Enum)(常用)
3)静态导入 (static import)
4)可变参数列表 (var args)(常用)
5)范型(Generic)(常用)
6)增强for循环(for-each)(常用)
7)注解(Annotation)(常用)
8)协变返回类型:实际返回类型可以是要求返回类型的一个子类
9)concurrent并发包(Doug leg)(常用)
JDK6(2006-12, LTS)
1)Compiler API,可以实现动态编译Java源文件,如jsp编译引擎就是动态的,修改后无需重启服务器
2)对脚本语言的支持:如js, ruby,groovy
注:因JDK6至JDK7中间间隔了足足5年,所以这个版本是个经典版本,很稳定,官方长期维护,使用了很长时间。
JDK7(2011-07, LTS)
JDK7版本从JDK6后5年才发布,原因是中间经历了Sun公司被收购。大体发布历程是:
2009 年 1 月, Sun 开始开发 JDK7 Milestone 1。
2009 年 11 月,Sun 在 Devoxx 2009 大会上宣布将闭包特性加入 JDK7,并将 JDK7 的发布日期推迟到 2010 年底。
2010 年 4 月,Oracle 收购 Sun。
2010 年 9 月,Mark Reinhold 在 JavaOne 大会上宣布 JDK7 将砍去 Lambda、Jigsaw 和部分 Coin 新特性并于 2011 年中发布,其余部分的新特性将于 2012 年底同 JDK8 一同发布。
2010 年 10 月,IBM 宣布加入 OpenJDK,将与 Oracle 合作共同开发 JDK。此后,Apple 和 SAP 也陆续加入 OpenJDK 社区。
2011 年 7 月 28 日,Oracle 正式发布 JDK7,并指定 OpenJDK7 为参考实现。
特性一:一组小的改进
1)Switch支持String(常用)
2)try … with … resource(常用)
3)范型类型自动推断(常用)
4)多重catch(常用)
5)数字可用下划线分割
特性二:G1垃圾回收器(Grabage-First Collector)(常用)
新出的垃圾回收器,用来替代Concurrent Mark-Sweep Collector(CMS)。目标是减少 Full GC 带来的暂停次数,增加吞吐量。
特性三:concurrent包改进(常用)
Doug Lea在此版本引入了轻量级的fork/join框架来支持多核多线程的并发计算。此外,实现了 Phaser 类,它类似于 CyclicBarrier 和 CountDownLatch 但更灵活。最后,ThreadLocalRandom 类提供了线程安全的伪随机数生成器。
特性四:IO与网络的更新
NIO2 主要包括了 3 个方面的改进:
- 新的文件系统 API 支持大量文件属性的访问、文件系统监控服务、平台相关的 API,如 DosFileAttributes 和 PosixFileAttributes 等,以及一个可插拔文件系统的 SPI。
- Socket 和文件的异步 IO。
- Socket channel 的功能完善,支持 binding、多播等。
特性五:JDBC更新(常用)
支持JDBC4.1和Rowset 1.1
JDK8(2014-03, LTS)
1)接口默认方法(常用)
即接口中可以声明一个非抽象的方法作为默认的实现,方法的返回类型前要加上“default”关键字
2)lambda表达式(常用)
3)函数式接口(常用)
指仅仅包含一个抽象方法的接口,需要标记@FunctionalInterface
4)使用 :: 来传递方法引用,是lambda的简写(常用)
5)Stream API(常用)
6)新的日期工具类(常用)
JDK9(2017-09)
1)模块化
即只加载应用运行需要的模块
2)改进的Java doc
生成的Java doc符合H5标准,支持API搜索
3)集合工厂方法,优化集合初始化(常用)
Set<Integer> ints = Set.of(1,2,3);
List<String> strings = List.of("first","second");
4)改进 Stream API
IntStream.iterate(1, i -> i < 100, i -> i + 1).forEach(System.out::println);
5)支持私有接口方法
6)HTTP/2(常用, 是预览版)
新的方式处理HTTP调用,用于替换 HttpURLConnection,并提供对WebSocket和HTTP/2的支持
7)多版本兼容
JDK10(2018-03)
1)局部变量类型推断(常用)
即只能作为局部变量类型,方法参数,返回类型等不可以。常见示例:
var str = "ABC"; //根据推断为 字符串类型
var l = 10L;//根据10L 推断long 类型
var flag = true;//根据 true推断 boolean 类型
var flag1 = 1;//这里会推断boolean类型。0表示false 非0表示true
var list = new ArrayList<String>(); // 推断 ArrayList<String>
var stream = list.stream(); // 推断 Stream<String>
2)并行full gc的G1
通过并行Full GC, 改善G1的延迟。目前对G1的full GC的实现采用了单线程-清除-压缩算法。JDK10开始使用并行化-清除-压缩算法。
3)基于实验Java的JIT编译器
启用基于Java的JIT编译器Graal,它是JDK9中引入的Ahead-of-time(AOT)编译器的基础。
JDK11(2018-09, LTS)
1)增加一些实用API(常用)
String str = "woshidage";
boolean isblank = str.isBlank(); //判断字符串是空白
boolean isempty = str.isEmpty(); //判断字符串是否为空
String result1 = str.strip(); //首尾空白
String result2 = str.stripTrailing(); //去除尾部空白
String result3 = str.stripLeading(); //去除首部空白
String copyStr = str.repeat(2); //复制几遍字符串
long lineCount = str.lines().count(); //行数统计
2)HttpClient增强(常用,已转换为正式版)
同时提供了同步调用和异步调用实现。JDK对http对调用支持已经足够强,以前apache提供的httpComponents基本可以去除了。
4)ZGC
JDK11最瞩目的特性,但目前是实验性质的。目标是GC暂停时间不会超过10ms,既能处理几百兆的小堆,也能处理几个T的大堆。
5)完全支持Linux容器(常用)
JDK10开始,JVM可以识别当前是否在容器中运行,能接受容器设置的内存限制和CPU限制。
JDK12(2019-03)
- Switch Expression
传统使用switch的方式:
switch (day) {case MONDAY:case FRIDAY:case SUNDAY:System.out.println(6);break;
case TUESDAY:System.out.println(7);break;
case THURSDAY:
case SATURDAY:System.out.println(8);break;
case WEDNESDAY:System.out.println(9);break;
}
如今可简化为:
switch (day) {
case MONDAY, FRIDAY, SUNDAY -> System.out.println(6);
case TUESDAY -> System.out.println(7);
case THURSDAY, SATURDAY -> System.out.println(8);
case WEDNESDAY -> System.out.println(9);
}
JDK13(2019-09)
- 字符串拼接
JDK13前:
String html = "<html>\n" +" <body>\n" +" <p>Hello, world</p>\n" +" </body>\n" +"</html>\n";
现在:
String html = """<html><body><p>Hello, world</p></body></html>""";
- 重写实现旧版套接字API
使用更简单、更现代的实现替换java.net.Socket和java.net.ServerSocket API使用的底层实现,易于维护和调试。新的实现很容易适应用户模式线程,也就是光纤。之前的底层实现可以追溯到jdk1.0,实现是遗留java和c代码的混合,维护和调试很痛苦,该实现使用线程堆栈作为I/O缓冲区,这种方式需要多次增加默认线程堆栈大小。
JDK14(2020-03)
- switch优化变为最终版
- gc相关
1)删除CMS
2)弃用 ParallelScavenge + SerialOld GC 的垃圾回收算法组合
3)将 zgc 垃圾回收器移植到 macOS 和 windows 平台 - instanceof 扩展 (preview)
传统instanceof使用方法:if (o instanceof String) {String s = (String)o;System.out.println(s.length); }
现在可以增强为:
if (o instanceof String s) {System.out.println(s.length);}
- 有帮助的NullPointerException
传统出现NullPointerException时的报错信息:
Exception in thread "main" java.lang.NullPointerExceptionat jdk14.NullTest.<init>(NullTest.java:16)at jdk14.Main.main(Main.java:15)
如果异常信息是链式调用时发生,如:a.b.c.d…, 此时很难直接定位NullPointerException发生在哪里。现在打印信息得到了增强:
Exception in thread "main" java.lang.NullPointerException:Cannot read field "c" because "a.b" is nullat Prog.main(Prog.java:5)
JDK15(2020-09)
JEP 385 Deprecate RMI Activation for Removal
RMI Activation被标记为Deprecate,将会在未来的版本中删除(JDK17)。RMI大家应该都清楚,RMI就是Remote Method Invocation,翻译成中文就是远程方法调用,是在JDK1.2中引入的。RMI为java提供了开发分布式系统的强大能力。而J2EE的规范EJB就是使用RMI来实现的bean的远程调用的。在RMI系统中,远程系统中存在很多分布式对象,如果这些分布式对象一直处于活动状态的话,将会占用很多宝贵的系统资源。于是RMI引入了一种lazy Activation的方式,这种方式就叫做延迟激活。对于现代应用程序来说,分布式系统大部分都是基于Web的,web服务器已经解决了穿越防火墙,过滤请求,身份验证和安全性的问题,并且也提供了很多延迟加载的技术。所以在现代应用程序中,RMI Activation已经很少被使用到了。并且在各种开源的代码库中,也基本上找不到RMI Activation的使用代码了。为了减少RMI Activation的维护成本,在JDK8中,RMI Activation被置为可选的。现在在JDK15中,终于可以废弃了。JEP 339 Edwards-Curve Digital Signature Algorithm (EdDSA)
实现了EdDSA椭圆曲线签名算法。JEP 375 Pattern Matching for instanceof (second preview)
该功能已经在JDK14初次引入,可看上文介绍JEP 384 Records (Second Preview)
引入了Record类型,解决定义大量get/set方法的问题,可一定程度替代掉lomobok
示例如下:
public record Address(String addressName,String city
) {}public record CustUser(String firstName,String lastName,Address address,int age
) {}
Record和普通的类的区别就在于Record多了一个括号括起来的定义的字段。
Record类默认是final的,里面的字段默认是private final的。
可借助IDE的反编译功能,反编译字节码可得到Record类的实现:
public final class CustUser extends java.lang.Record {private final java.lang.String firstName;private final java.lang.String lastName;private final com.flydean.records.Address address;private final int age;public CustUser(java.lang.String firstName, java.lang.String lastName, com.flydean.records.Address address, int age) { /* compiled code */ }public java.lang.String toString() { /* compiled code */ }public final int hashCode() { /* compiled code */ }public final boolean equals(java.lang.Object o) { /* compiled code */ }public java.lang.String firstName() { /* compiled code */ }public java.lang.String lastName() { /* compiled code */ }public com.flydean.records.Address address() { /* compiled code */ }public int age() { /* compiled code */ }
}
可以看出Record类继承自Record类,属性默认private final,这意味着Record实例是immutable(不可变的), 且有一个默认的包含所有参数的构造方法,其他如toString(), hashCode(), equals()已得到了默认实现。
对于Record可以做一定限度的定制,如校验属性,定义新属性。
public record CustUserWithBody(String firstName,String lastName,Address address,int age
) {public String fullName(){return firstName + lastName;}public CustUserWithBody {if (age < 18) {throw new IllegalArgumentException( "年纪太小");}}
}
JDK16(2021-03)
- instanceof 增强确定为最终版本,该功能已经在JDK14初次引入,可看上文介绍。
- Records确定为最终版本,该功能同样也已经历了两代预览版,可看上文介绍。
- 387: 弹性Metaspace功能可将未使用的HotSpot虚拟机的Class Metadata(Metaspace)占用的内存更迅速的返回给操作系统,从而减少Metaspace的占用并简化Metaspace的代码以降低维护成本。
- 388: 将JDK移植到Windows/AArch64平台。
- 392: 提供用于打包独立的Java应用程序的jpackage工具。
JDK17(2021-09, LTS)
该版本是继JDK11之后3年新推出的长期支持版本。
- JDK 内部的强封装,除了sun.misc.Unsafe等关键的内部 API 外,用户将不再可能通过单个命令行选项来 relax 对内部元素的强封装,这在 JDK 9 到 JDK 16 中是可行的。该计划的目标包括提高 JDK 的安全性和可维护性,并鼓励开发人员从内部元素迁移到标准 API。
- 删除远程方法调用 (RMI) 激活机制,同时保留 RMI 的其余部分。RMI 激活机制已过时和废弃,在 JDK 15 中不推荐使用(可参考上文JDK15部分的描述)。
- 删除实验性 AOT 和 JIT 编译器,它们几乎没有使用,但需要大量维护工作。该计划要求维护 Java 级别的 JVM 编译器接口,以便开发人员可以继续使用外部构建的编译器版本进行 JIT 编译。
- 将 JDK 移植到 MacOS/AArch64 以响应 Apple 将其 Macintosh 计算机从 x64 转换到 AArch64 的计划(Apple M1处理器)。针对 MacOS/AArch64 的更改有可能破坏现有的 Linux/AArch64、Windows/AArch64 和 MacOS/x64 port,但这种风险可通过预集成测试来降低。
- 弃用 Applet API 以进行删除。这个 API 本质上是无关紧要的,因为所有 Web 浏览器供应商要么已经取消了对 Java 浏览器插件的支持,要么已经宣布了这样做的计划。Applet API 之前在 2017 年 9 月的 Java 9 中已被弃用,但并未删除。Applet API彻底被删除,最早java就是靠applet开始火的。
- 弃用 Security Manager,准备在未来版本中移除。追溯到 Java 1.0,Security Manager 一直是保护客户端 Java 代码的主要手段,很少用于保护服务器端代码。该提案的一个目标是评估是否需要新的 API 或机制来解决使用 Security Manager 的特定狭窄用例,例如阻塞System::exit。计划要求弃用 Security Manager 以与旧 Applet API 一起删除,该 API 也计划在 JDK 17 中弃用。
总体来说JDK17没有在语言层面有新的改进。
JDK18(2022-03, Coming soon)
OpenJDK vs OracleJDK
市面上有各种jdk,最权威的是官方发布的oracle jdk,其他的还有adoptopenjdk, azul zulu jdk, Amazon Corretto, alibaba dragonwell, Temurin等。 oracle jdk 和Open jdk有什么区别?为什么又冒出各种各样的jdk? Oracle jdk从2019年之后需要商业收费,公司该如何选择?本节将对这些问题做一些澄清。
OpenJDK可理解为两个:源代码存储库和发行版本。
源代码存储库角度: 就源代码而言,只有一套Java源代码,存在OpenJDK项目中,地址是:https://github.com/openjdk/jdk。 这个项目由Oracle公司主导,还有很多大公司参与合作开发,如:IBM, Apple, Microsoft等。
发行版本角度: 各个公司基于同一套源码,加上一些自己的实用工具,为不同的平台(os:Linux, Mac, Windows; 架构:aarch64, x64)编译出二进制包,并附上授权声明,提供给大家下载使用。 各个不同的发行版本也会承诺如有版本更新也会及时释出新版本。
OracleJDK从9开始一样是基于OpenJDK,它额外的提供了一些闭源组件,以及商用license。可以理解为OracleJDK和OpenJDK源码几乎就一样,使用Oracle JDK需要付费,同时也能得到相应的服务: 客服支持,版本更新以及一些实用工具。
主流OpenJDK 发行版介绍
Temurin OpenJDK
原来是AdoptOpenJDK ,是2017年,一群Java用户组(JUG)成员、开发者和供应商(包括亚马逊、微软、Pivotal、Redhat等)建立了一个社区称作AdoptOpenJDK。他们提供免费、稳固的OpenJDK build,可用性与更新周期更长。甚至还有两个不同的Java虚拟机可供选择:HotSpot和OpenJ9。
目前它已归属于Eclipse 基金会,下载地址:https://adoptium.net/
该版本是大多数用户(无特殊功能要求)的最佳选择。
Oracle OpenJDK
oracle自己也基于OpenJDK编译了一套发行版,去除了商标,并且免费,但不承诺会及时更新。
Azul Zulu OpenJDK
官方称是世界上最大的OpenJDK商用提供商。它自家闭源的zing jvm在hotspot jvm的基础上进行了大量优化。zulu是Azul提供的开源版本,可自由使用,但不提供支持。 需要支持可选用商业版本:
商业版本分为两种:
Azul Platform Core
即之前的zulu enterprise/embedded版本Azul Platform Prime
即之前的zing。它提供更优秀的性能。
zulu是本人比较喜欢的版本。下载地址:https://www.azul.com/downloads/?package=jdk
Microsoft OpenJDK
微软也发行了自己的openJDK版本,且不仅仅是Windows版本, macOS, Linux也有对应释出版本。果然Microsoft越来越开放了。 按微软的说法其Azure, SQL Server, Visual Studio Code, LinkedIn等都使用了java技术。
微软提供的软件质量肯定是妥妥的,用于生产都没什么问题,下载地址:https://www.microsoft.com/openjdk
Dragonwell OpenJDK
最后一个介绍一下阿里释出的发行版,命名为龙井。Alibaba Dragonwell 是一款免费的, 生产就绪型Open JDK 发行版,提供长期支持,包括性能增强和安全修复。阿里巴巴拥有最丰富的Java应用场景,覆盖电商,金融,物流等众多领域,世界上最大的Java用户之一。Alibaba Dragonwell作为Java应用的基石,支撑了阿里经济体内所有的Java业务。
阿里生产环境使用的OpenJDK,质量也是经的起考验,需要注意的是:
- Alibaba Dragonwell 会针对 Long Term Support(LTS) 提供 Java 8 和 Java 11两个版本
- Dragonwell随阿里云 VM 镜像发布,免费提供给阿里云客户使用;开发者也可以直接下载免费使用
- 阿里巴巴提供季度更新,Java8 更新至少到 2023 年 6月,Java11 更新至少到 2024 年 6月
- 目前仅支持Linux下的x64架构
下载地址:https://www.aliyun.com/product/dragonwell
用户JDK版本选择
- 有商业支持需求的选择Oracle JDK。 如果对性能方面有更高要求的选Azul Platform Prime, 即zing jvm。
- 免费用户无特殊要求的选Temurin OpenJDK即可。
- 有特殊架构需求的,如Mac m1(aarch64)有时释出版本受限,可选择zulu OpenJDK。
1. JDK版本变迁和各版本新特性相关推荐
- JDK/Java 14 可能带来什么新特性?
JDK/Java 13 在一个月前已经发布,该版本带来了 5 大新特性,笔者观察到其中的 Text Blocks(文本块)特性似乎被讨论最多.文本块特性与常见的 Python "" ...
- SpringBoot 3.0最低版本要求的JDK 17,这几个新特性不能不知道!
△Hollis, 一个对Coding有着独特追求的人△ 这是Hollis的第 387 篇原创分享 作者 l Hollis 来源 l Hollis(ID:hollischuang) 最近,有很多人在传说 ...
- oracle11gR版本GI中新增,Oracle11g新特性MemberKillEscalation简介
从oracle 11gR1 开始,Member Kill Escalation的出现成功的解决了前面提到的情况.当实例eviction在指定的时间内(默认20秒)不能 首先我们介绍一下历史.在Orac ...
- oracle enlist,针对各版本的 .NET 的 Oracle 新特性
各版本的 ODP.NET 新特性 11.1.0.7.20 版 Oracle Streams Advanced Queuing:使用 Oracle 数据库集成的队列构建 .NET 消息处理应用程序 可提 ...
- jQuery 1.4 版本的十五个新特性-转载
jQuery 1.4 最近发布了. 超乎大家的预期,这次并非简单的修修补补,1.4 包含了很多新特性.功能增强和性能提升!本文即向您介绍这些可能对你十分有用的新特性和优化增强. 你可以立刻下载jQue ...
- 我还在生产玩 JDK7,JDK 15 却要来了!|新特性尝鲜
自从 JDK9 之后,每年 3 月与 9 月 JDK 都会发布一个新的版本,而2020 年 9 月即将引来 JDK15. 恰巧 IDEA 每四五个月会升级一个较大的版本,每次升级之后都会支持最新版本 ...
- 本周推荐 | JDK 11 升级实践 和 Java 新特性浅探
推荐语:学习java和jdk的新特性并积极应用,以达到优化系统,降本提效的作用,这是我们作为java研发同学的第一节课.本文从"为什么"起手,谈到"怎么做",最 ...
- Java春招面试复习:JDK 5-15都有哪些经典新特性
前言 JDK 15发布啦~ 我们一起回顾JDK 5-15 的新特性吧,大家一起学习哈~ 本文已经收录到github https://github.com/whx123/JavaHome 公众号:捡田螺 ...
- JDK/JAVA 13正式版发布,此版本带来了以下几大新特性
JEP 350,Dynamic CDS Archives:扩展应用程序类-数据共享,以允许在Java应用程序执行结束时动态归档类.归档类将包括默认的基础层CDS(class data-sharing) ...
- Python 3.9 beta2 版本发布了,看看新特性?
随着 Python 3.9.0b1 的发布,即开发周期中计划的四个 beta 版本的首个,Python 3.9 的功能已经是完善了.在 10 月发布最终版本之前,还会有许多测试和稳定性方面的工作要做. ...
最新文章
- LINUX 查找tomcat日志关键词
- clion pycharm goland 设置背景颜色
- 【转载】PHP报错分析(Corrupted encoded data detected in)
- Citus中的分片策略:Append Distribution追加分配
- STL Priority_Queue
- [转] CMake入门
- Z.ExtensionMethods 一个强大的开源扩展库
- 改善Java应用程序性能的快速技巧
- mariadb数据库增删改查
- 操作系统知识点大总结
- 游侠原创:手机电子商务与社交隐私--网络安全的下一个关注点
- 为了有一些储蓄,把自己压榨到最狠的时候是怎样的?
- 0004-程序流程2之ui-router大意
- Java内部类最细详解
- 通过DriverManager接口获取连接
- windows系统下运行bat脚本实现后台运行及停止jar文件
- web文件服务器1台,WEB服务器及配件1台 - 千里马招标网
- CSS动画效果(animation属性)解析
- 计算机考研数学和英语难吗,英语难还是数学难
- mysql是一个大型数据库_MySQL是一个大型关系型数据库管理系统(RDBMS)。