【精选】1. JDK版本变迁和各版本新特性

您所在的位置:网站首页 oracle版本发布时间 【精选】1. JDK版本变迁和各版本新特性

【精选】1. JDK版本变迁和各版本新特性

2023-10-26 02:26| 来源: 网络整理| 查看: 265

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 ints = Set.of(1,2,3); List strings = List.of("first","second");

4)改进 Stream API

IntStream.iterate(1, i -> 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(); // 推断 ArrayList var stream = list.stream(); // 推断 Stream

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 = "\n" + " \n" + "

Hello, world

\n" + " \n" + "\n";

现在:

String html = """

Hello, world

"""; 重写实现旧版套接字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.NullPointerException at jdk14.NullTest.(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 null at 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


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3