Java 17:路径、特性、技巧和窍门小组
文字稿
贝克维思。我是Monica Beckwith。我是微软的JVM架构师,在OpenJDK、Sun JDK等领域与HotSpot JVM合作了很长时间了。在这个小组中,我想谈一谈Java 17,以及导致我们走到今天的一切原因。
O'Leary:我的名字是Kristen O'Leary。我是谷歌的高级开发者关系工程师。我在谷歌云工作,从事Java客户端库的工作,都是开源的,都是有趣的东西,特别是在云原生数据库方面。
里特。我是Azul的副CTO。我是Simon Ritter。我从一开始就与Java打交道,因为我早在1996年就加入了Sun Microsystems,大约是在JDK 1.0出来的时候。我一直关注着它,经历了Sun公司的岁月,Oracle公司的岁月,现在在Azul。
Preddy。一个为微软工作的开发者倡导者,他使用带有Chrome浏览器的苹果电脑,他倡导使用Java。这对我来说是一种讽刺。
什么是(JEP)Java增强建议?
贝克威斯。什么是JEP,即Java增强建议?因为我知道我们会在这里谈论JEP,有多少JEP进入了Java 17?
里特。JEP很有意思,因为如果你看一下Java的发展方式,我们有Java社区进程。这是由Sun Microsystems开始的,大概是在2004年、2005年左右。这是一种试图解决开发者的需求的方式,即为Java制定一个更正式的标准,而不一定是由Sun控制。他们启动了Java社区进程,我们有所谓的JSR,即Java规范请求,这就是Java的不同方面。有一个专家小组负责这个问题。我是Java SE标准的专家小组成员,这确实是我们用来开发Java新功能的方式。因为我们已经转向了OpenJDK的开源模式,我们所看到的是,开发人员希望有更多来自少数公司以外的贡献。他们创造了 "JDK增强建议 "这一概念。JEPs是关于合理规模的工作,需要花费相当多的时间来实际创建,任何OpenJDK的提交者,所以不仅仅是甲骨文,任何有提交者身份的人都可以提交JEP,提出一个新功能的想法,无论是在语言中,还是在库中,或者是在JVM中。这是一个关于Java如何发展的3年计划。这是描述JEPs的最好方式。
Java发布周期,以及(LTS)长期支持
Beckwith。你谈到了3年计划。还有这整个发布节奏,最近,实际上,LTS的持续时间略有减少,我想。克里斯汀,你想谈谈发布周期,甚至是LTS的含义,以及我们在LTS周期中的情况吗?
O'Leary:LTS就是长期支持。这意味着每隔一段时间,某些版本(17是其中之一)会比非LTS版本的支持时间更长。很多时候,开发者会选择使用LTS版本,因为他们知道它会得到长期的支持。在发布节奏方面,有趣的是,我记得,我相信是在Java 8发布之后,发布节奏真的加快了。它比我记忆中的之前要频繁得多。我确实记得在7和8之间有一个很大的差距,然后突然之间,就像9、10。现在我们一直到了17岁。我想说这是每六个月一次。看到这么多的新版本更频繁地出现,新的JEPs被发布,无论是预览版还是GA版,都让人兴奋。
Preddy:我想发生的事情是人们已经习惯了这种节奏,他们说更多,他们希望这些功能从预览版中出来,并在他们手中。然后马克-莱因霍尔德居然说,这很有效,让我们再快一点,而那些可能在甲骨文手下的可怜的开发者就说,"不,请,只是我们现在不管理。"
瑞特。我认为,因为转换发生在JDK 9,甲骨文会告诉你,JDK 9是Java的最后一个主要版本,意味着它背后有多年的努力。我们在不同的JDK版本之间有很长的时间,我想6到7是最长的一次。当时的Java版本间隔超过四年。现在我们每六个月发布一次,这确实比我们以前看到的快得多。这似乎是非常好的工作。这样做的一个真正好处是,我们可以有这种预览功能的想法,即我们引入一个功能,但不直接将其作为标准的一部分。征求反馈意见,了解人们对它是否有效的看法。然后在它真正被纳入标准之前,仍有时间进行修改。
Preddy。我非常怀念的一件事是实验室内的活动,以及能够做的事,并与生态系统一起充满活力。现在,当我提到代码时,没有那种感觉,你在用什么IDE?你在使用那个IDE吗?看看我在那里用什么。开发者与它有一点竞争。我非常怀念这一点。西蒙会提出NetBeans,而我则会提出Visual Studio Code,我们会有那么一点像挑逗的感觉。我很怀念这种情况。
瑞特。实际上,我已经做了转换。我已经离开了NetBeans。IntelliJ。
O'Leary: 我也是IntelliJ的。
Beckwith:我仍然是NetBeans。我喜欢NetBeans。
Ritter:我喜欢NetBeans。我的问题是,它对变化的跟踪还没有达到应有的速度。我想使用17种功能,而NetBeans还没有达到这个要求,所以IntelliJ。我应该试试Visual Studio,但这有点难。
Preddy。不,Visual Studio Code。
Ritter:Visual Studio代码。
Preddy。虽然那是单片机的小版本,我们刚刚达到100万用户。如果你考虑一下,600万Java开发者,其中六分之一的人使用Visual Studio Code与Java。
Java 17预览版的特点
贝克威斯。西蒙,你提到了关于使用Java 17的功能。你是在说预览版还是在说真正进入17版的一个功能?
里特。在这种情况下,它是预览功能,因为我正在看switch的模式匹配。我正在做一个研讨会,我想测试一下我在这方面使用的一些代码。我需要能够使用这个。这就像,是的,我要用IntelliJ来做这个。
从Java 11到Java 17-Plus的首要特征
Beckwith。Rory,你呢?哪些功能,让我们从11开始,一直到17,当然还有预览版,所以17-plus。如果你必须列出前三名,你的第一个会是什么?
Preddy:说到云,我都是为了本金。我在西雅图的一家小型创业公司工作,微软,我们有一个宏伟的云。有了这个云,我们就有了所有这些功能,而且很多都是按秒计费。当开发人员来找我时,他们会说,这很好,让它更快,让它更快,以及所有的东西。我一直在关注垃圾收集,每个人都有所有这些指标。第一件事,你想知道一个开发人员做了什么,所有的Java冠军,他们去,"我有这个,那个,那个。然后我让它走得更快,"以及诸如此类的一切。这很好,一切都很好,但在每个云上弹出它,然后告诉他们它运行了多少毫秒。最大的问题是,这一切都运行在容器化管理程序上。垃圾收集器在其中运行得很好,现在把它放在Docker、Docker和Docker Compose上,看看它是否在那里运行。我们仍在研究如何利用所有这些垃圾收集器为我们的客户更好地节约成本。我真的很关注这一点。
其次,我和数以百万计的刚刚开始使用Java的开发者交谈,记录是一种很好的方式,可以说我们对那些模板感到抱歉。我们知道你不能放任不管,但我们用记录来摆脱了getters和setters。这是一个很好的方法。自从我的表弟C#有了getters和setters,我就一直在说这个。我对他们说,我们最终会得到它。我们得到了它。我真的很热衷于记录。最后,我也喜欢这个想法,飞行记录器和剖析器被包括在内,虽然是标准配置。Java开发者只有在他们引以为豪的代码中才是好的。他们应该有足够的自豪感,能够真正走进去,看看他们所有的代码,然后说,我在应该使用字符的时候使用了字符串,在应该使用这些集合的时候使用了列表。对我来说,这是个提高性能的好机会。
Beckwith:Kristen,你自己呢,有什么想说的功能吗?
O'Leary:我将提出一些其他的东西,我认为这真的只是一个很好的便利功能,即字符串格式化。基本上,假设你在处理像JSON字符串这样的东西,它缩进了很多行,只是为了打印出一些blob,或对象,或其他东西,如果你想把它设置为一个字符串,粘贴到代码中会很烦人。使用字符串格式化,你可以在顶部做三个引号,放入所有的文本,然后在底部做三个引号,在你的代码中看起来更漂亮。同样,这可能是与性能或优化或任何东西有关的东西。对我来说,作为一个阅读代码的人,我认为这是很好的。我认为它也会在单元测试等事情上派上用场,在那里你要解析模拟的JSON,而只是为了测试你的代码。我绝对认为它值得一试。我认为它只是让开发者的可读性生活更容易,或者让审查你代码的人更容易。它看起来更漂亮,我认为这是一个非常好的补充。
瑞特。很明显,我重申Rory和Kristen已经说过的话。记录,这只是一个伟大的事情。我还是很难想象我们花了这么长时间才得到Java中元组的概念,以及用简单的方式来表示这样的东西的能力。很高兴看到记录,使生活变得更容易,减少了模板代码的数量。我确实喜欢多行字符串或文本块,就像我们所说的那样,以及在这方面使你的生活更容易的能力。另一件我非常喜欢的事情是有用的空指针异常。同样,我们花了25年的时间才发现,如果能弄清楚空指针的实际发生地,也就是A.B.C.什么的,那将是非常好的。当然,我们现在有能力看到空指针在链中实际发生的位置,这很好。在减少模板代码的数量方面,他们做了很多很好的小事情,使开发者的生活更容易。记录就是一个很好的例子。模式匹配,以及对实例的引入,还有我们在JDK 17中看到的开关语句和开关表达式。所有这些东西都使开发人员的生活变得更加轻松,消除了一些粗糙的边缘。
JEP是如何被接受发布的
Beckwith:JEP是如何被接受为下一个版本的?每个JEP的项目管理是怎样的?
我可以从这个方面入手。我知道Azul也为多个做出了贡献。Azul也有一些提案。关于JEP的整体情况是,你有一个项目或者你心中有一个项目,你认为你可以做出贡献。你也可以从单纯的讨论到实际实现你所提议的项目。例如,微软,我们提议在Arm上移植Windows。我们这样做的方式是,我们确保我们有一些工作。我们做了测试,所以我们有一个CI/CD管道在工作。然后我们对社区说,我们想把它贡献给社区,因为我们的产品需要Java来工作,特别是Surface Pro X。社区非常开放,他们希望能在Windows on Arm上工作,但我们的这一重大贡献,他们也非常乐意接受。
JEP从提案状态到各种不同的状态,它必须被接受,必须被提议为目标。然后它必须被实施,然后成为目标。它经历了不同的阶段。如果你去看JEP,我想我们是在JEP 2.0。请随意阅读它所经历的不同步骤。然后就在这个JEP提出之后,我们也得到了Azul Systems的这个JEP,实际上就是Arm64上的MacOS。由于我们做了最初的工作,使其在Arm64方面的代码基础更加通用,所以MacOS也可以被插入其中。这就是进入Java 17的JEP之一。
来自Azul系统的JEP建议
西蒙,你想谈谈Azul所提出的新建议吗?
Ritter。JEPs是一个有趣的想法,因为有数以百万计的开发者在使用Java。你不希望的是突然对它进行大量的修改,从而影响到诸如向后兼容性之类的东西,并使开发者更难。我们的想法是,你必须非常谨慎地对待你所做的改变。这意味着,当JEP被提出时,你必须对实际要发生的事情有一个好的想法。它必须以一种OpenJDK社区的其他成员能够看到它并说,是的,这实际上是有意义的。我想我们是除甲骨文之外,第一家真正向JDK添加JEP的公司,我们只是向线程类添加了一个方法。这方面的工作量确实相当大。这很好,因为你不希望人们向线程或可运行类或核心类添加方法,只是说,"我认为这是一个好主意,让我们把它放在那里,看看会发生什么。"我们不得不通过一系列的步骤来实现这一目的。真的,JEP的问题是,你需要证明这将是可行的。你实际上必须带着代码来,而不仅仅是一个想法,带着代码来,带着概念证明来,确保所有的工作,并且你可以证明它。然后向人们证明,这实际上是可行的,并且可以作为一个整体被纳入OpenJDK。这是个不错的过程。它能很好地保持Java向前发展,但并不是人们可以随便把想法扔进去,然后说:"让我们试试这个。让我们试试那个 "之类的事情。
Java升级过程和新版本的推出
贝克威斯。我们能谈谈升级过程和向开发团队推出较新的Java版本吗?我认为这取决于不同的组织,以及开发团队喜欢如何跟上它,以及他们对底层库和其他API调用的依赖性,如果他们已经转移到下一个级别,或者没有。我认为这与下一个问题有关,为什么有那么多的组织还停留在Java 7和8?
Preddy:我帮助倡导了Codespaces。Codespace的其中一个功能是远程容器。这是GitHub Codespaces使用的一个功能。远程容器的作用是,它允许你启动一个Docker实例,你可以测试你的实例。你可以在上面运行一个完整的环境。GitHub Codespaces,你可以从2个CPU一直运行到32个CPU。我现在醉心于权力,因为这意味着我的GitHub仓库里有所有这些项目,而且我不必带着我的小MacBook Pro,也不必安装30个不同版本的JDK。任何时候我都可以旋转一个实例,看看有什么问题,如果确实有问题,然后把它带回家给老Mackie说,"我知道我得到了什么。"我们已经看到了很多进入容器的运动,通过测试容器使这种生活更容易。为什么不把你的整个环境旋转起来呢?现在就开始使用GitHub Codespaces,我可以帮助你完成这个任务。这只是我们前进的方式。为什么我必须在一个可重复的环境中工作?我想我的MacBook上有7个JDK,只是在那里漂浮着,但现在可能还有40个在GitHub Codespaces上,我不必担心,它们对我来说是牛,而不是猪。我喜欢这样。
瑞特。我认为从这个问题来看,人们都在谈论仍然运行JDK 7和JDK 8。我知道,我们遇到了很多运行旧版本Java的客户。我们支持JDK 6,但我们与仍在运行1.4.2、1.3的客户交谈,这有点吓人。我认为这个想法是,你需要考虑如何将大的开关从8迁移到9以上,因为你必须适应模块化的想法。这确实引入了一些有趣的东西。这更多的是与内部API的封装有关,这对你如何将你的应用程序迁移到其他地方有影响。在这方面已经做了大量的工作。现在,人们真正关注的是从8版本转移,这是一个长期支持版本。他们正在转移到11,那是以前的长期支持版本,现在17是当前的长期支持版本。这是一个想法,即我们确实有这些特定的版本,它们有扩展的更新可用。那些正在寻找长期使用该特定平台的人,他们正专注于这些。不一定要转到15、16、18、19等版本,而只是专注于那些有扩展更新的产品。
O'Leary:我认为重要的是,为什么Java 17特别令人振奋,因为它是LTS,我想我们都理解并能体会到我现在不能升级的痛苦,因为XYZ。我自己在以前的生活中也有过这样的经历,而且完全理解。我想这就是为什么看到17号是LTS的原因,而且随着发布周期的增加,希望我们能以这种速度得到更多的LTS。
瑞特。是的,因为这是17版发布后的一个重大变化,我们看到甲骨文已经提议,我相信现在可能已经接受了,我们将把长期支持版本之间的间隔从三年改为两年。下一个版本将是JDK 21。
Beckwith。这就是有人说的,当他们的组织达到17岁时,Java将达到它的第100个版本,这很奇怪。在很长一段时间里,我们都停留在JDK 7上,因为我一直在性能团队,所以要跟上下一个版本,以及维护性能和其他东西,并与性能更新有关。这些在当时都是存在的。只是想到Java的发展速度比我能跟上的速度还要快,这对我来说太不真实了,因为我在老团队工作,已经习惯了这些东西。
瑞特。我刚刚算了一下,在2025年,我们会有JDK 25。
Beckwith。我不知道Azul是第一家提出JEP的非Oracle公司。
瑞特。我认为我们应该公平地对待这个问题。我不认为我们是第一个提出JEP的公司。我认为我们是第一个真正将其纳入OpenJDK的公司。
很有趣的是,我们看到了很多工作,实际上我认为这是一件好事,因为这意味着OpenJDK的管理,以及Java的发展是非常好的控制。我们不是仅仅因为我们认为做这个或做那个会很好,就添加东西和扔东西进去。我不得不说,像Brian Goetz、Mark Reinhold和John Rose这样的人,他们确实是OpenJDK的架构师,他们在整合所有这些想法方面做得非常好,因为人们不断提出大量的好主意。"是的,让我们来做这个。让我们这样做。让我们包括多重继承。是的,我们不要。让我们包括运算符重载。不,我们不要那样做。"诸如此类的事情。
Java预览功能、孵化器和弃用问题
Beckwith。西蒙,你提到了预览和孵化器。除了模式匹配之外,你想谈谈你过去尝试过的一些孵化器,它们已经改变或被删除,因为这也发生过。
瑞特。我们还没有看到任何被移除的情况。我认为这可能是不太可能的。在一个极端的情况下,我们可能会达到这样的地步:一个功能,真的是人们不喜欢它,所以他们真的删除它。同样,我认为建筑师们有足够的知识,他们知道哪些事情是有意义的。我们肯定看到了来自开发者的反馈,这已经产生了影响。如果我们看一下像切换表达式这样的东西,那是第一个作为预览功能出现的。他们建议,对于旧式语法和开关表达式的组合,应该使用break和一个将从表达式返回的值。这是对break操作符的重载,它可以工作,因为你可以从switch语句中断开,你可以从循环中断开到一个标签。一个标签不能以数字开头,所以你可以用一个带有数字的break来脱离switch表达式。人们认为这有点太重了。他们说,让我们使用别的东西。开发人员回去后说,我们用 "产量 "代替 "中断"。这确实让事情变得更清晰。我认为这是一个很好的例子,说明了开发者的反馈如何影响了JEP最终的工作方式,一个新的功能最终也是如此。我们在多行字符串中也看到过这样的例子,加入了一些新的转义字符和类似的东西。这绝对是非常好的工作。
贝克威斯。Rory,关于预览功能或孵化器,甚至是已经存在的一些功能的废弃和移除,例如,RMI,或类似的东西,你想谈谈吗?
Preddy:我在想我最后一次真正运行RMI激活的时间。我第一次真正使用Java的时候,CORBA还是一个东西。我们会在那里创建我们的 ORB,我会连接到一个银行,我会把钱吸出来,我还会做其他事情。我当时想,"不,不要把它拿走。我靠这个谋生,不要把它拿走。"当它离开时,我想,好吧,也许这是一件好事。然后,最糟糕的事情是摆脱了那些XML绑定库,因为我没有意识到有多少人真的在使用它们,有多少库,而突然间,Java 9就把一切都杀了。我当时想,我们需要转到JSON。这让我退缩了很久。我敢肯定,现在仍有一些库因为使用JSON而完全损坏。人们还在使用Java 8,并且要去,那里有一些事情正在发生,我不能转移到那里。他们仍然在破坏变化。我和周围的客户谈过,他们都是从Java 8一路走过来的。
RMI的激活,它只是唤起了我的回忆。它也让我看到了我们现在要包括的新的RPC内存。我非常热衷于此,因为分布式和本地化以及所有的东西,这就像个人电脑的退潮。你得到了一个强大的PC或一个强大的服务器,然后我们从那个地方移开,现在我们要回到某个地方,某个地方有内存,我们要去使用它的内存而不是本地的内存。真的很想看看上面发生了什么。这意味着,像这里的物联网设备可能有内存,我可以用Java和它对话,我可以让它做一些事情。我真的很想知道这一点。
贝克威斯。关于XML绑定的问题,有一些基准。人们知道SPEC基准测试委员会,所以他们的基准SPECjbb2015,然后是SPEC SERT,他们有很多的依赖性。SPEC SERT有一个对[听不清 00:33:18]的依赖性。看到他们如何打破和我们如何适应总是很有趣。这些基准仍然在那里。他们只是适应了这些变化。
O'Leary: 我能想到的一个,那是前一阵子,我实际上正在为某个会议做一个演讲。那时候9号文件还没有发布,但就快发布了,所以我在使用它。很明显,这是一段时间以前的事情了。我当时正在做他们改变反射规则的工作,以及你可以用反射做什么,以及你被允许和不允许做什么。我记得在某些调用中,我第一次使用JDK 9构建时,它失败了,说错误,你不能使用,我想是[听不清 00:34:13],或者是什么。然后几周后,我在练习我的演讲时,我一定是得到了一个较新版本的JDK。我想,由于反馈,他们实际上软化了它,所以它不再是一个失败,而是一个警告。以前你必须在命令行中手动覆盖它,说它是好的,只要给我一个警告,不要失败,而他们把警告换成了默认。我认为这很有趣,这些围绕反射的新规则的严格程度是如何改变的,我想是基于反馈和人们说:"我们不能那么快迁移我们的代码。不要再让我们失望了。先给我们一个警告,再给我们一些时间"。这就是我想到的,同样是几年前的事,但我认为这很有趣。
Ritter。这实际上是JDK 9两次被推迟的原因,因为有很多关于封装内部API和反射效果的反馈。OpenJDK的开发者实际上不得不回头说,是的,如果我们直接这样做,我们会破坏太多的东西。有趣的是,JDK 17实际上也稍微改变了这一点。他们引入了所谓的大杀器,也就是JDK 9中引入的--非法访问标志。JDK 9中的默认值是允许访问,所以你仍然可以做所有你以前可以做的事情。然后在JDK 16中,他们把它变成了拒绝,所以默认情况下关闭了访问,但你仍然可以把它重新打开。在JDK 17中,他们基本上让非法访问标志不发挥作用。他们对事物的限制更多了。有些东西仍然可用,比如sun.misc.Unsafe,你仍然可以实际访问。这是关于JDK 17的一件重要的事情,你需要测试你的应用程序。因为如果他们确实使用了任何内部API或以特定的方式进行反射,他们现在可能真的会崩溃,或者不能以你期望的方式工作。
贝克威斯。Kristen,当你提到你的演讲时,我正在做一个关于G1垃圾收集器的演讲,我想花哨一点,展示一下日志。在JDK 9之前,GC日志是与每个垃圾收集器相关的,而且其粗略程度就像垃圾收集器想要分享的那样。然后我们转到了统一的日志,这很好,但它破坏了我所有的解析器和所有的东西。我有这个演示,我很清楚我想做什么,但我只想展示这个打印自适应大小的策略,这是对GC如何自适应的更多粗略的输出。我想在JDK 9中展示它,因为这是最酷的事情。然后我就想,我不知道该怎么放。当然,有日志本身,但随后解析器必须从日志中提取某些值,然后绘制出来。这就是我正在做的事情。这很有意思。最后的结果非常好。我有过的恐慌,比如,我必须改变我的分析器。这些绘图器是基于JFreeChart的,还有其他一切。有趣的时光。统一日志是朝着正确的方向迈出的一大步,虽然我们确实看到事情有了些许变化,但我认为解析器很容易。我可以用同样的G1解析器来进行并行的GC和CGC以及类似的一切,只需做很少的修改。
Azul Prime和Zulu
里特。我为Azul工作,所以我们做Java,所以我们称之为Zulu,这是我们构建的OpenJDK,或者我们称之为Prime,这是我们增强的OpenJDK构建,做高性能、低延迟、高吞吐量的应用。