这是优锐课为你整理的你需要了解的有关不同Java版本和功能的所有信息。
你可以使用本指南查找和安装最新的Java,了解Java发行版(AdoptOpenJdk,OpenJDK,OracleJDK等)之间的差异,以及获得Java语言功能的概述,包括Java版本8-13。
背景资料
首先,让我们看一下人们在尝试为其项目选择正确的Java版本时遇到的一些常见的实际问题。
如果要了解有关特定版本的更多信息,请转到AdoptOpenJDK网站,选择最新的Java版本,下载并安装它。 然后回到本指南,仍然学习有关不同Java版本的一两个东西。
我应该使用哪个Java版本?
截至2019年9月,Java 13是最新发布的Java版本,每6个月更新一次版本——Java 14计划在2020年3月发布,Java 15计划在2020年9月发布,依此类推。过去,Java的发布周期更长,最长可达3-5年!
随着许多新版本的出现,基本上有以下实际使用场景:
• 公司中的遗留项目经常被Java 8卡住。因此,你也将被迫使用Java 8。
• 一些遗留项目甚至被卡在了Java 1.5(2004年发布)或1.6(2006年发布)上——抱歉,朋友们!
• 如果你要确保使用最新的集成开发环境、框架和构建工具,并开始一个全新的项目,你可以毫不犹豫地使用Java 11 (LTS),甚至是最新的Java 13。
• 在Android开发的特殊领域,Java版本基本上停留在Java 7上,并提供了一组特定的Java 8功能。或者,你可以切换到使用Kotlin编程语言。
为什么公司仍然坚持使用Java 8?
公司仍然坚持使用Java 8的原因有多种,有多种:
• 构建工具(Maven、Gradle等)。)和某些库最初具有Java版本> 8的错误,并需要更新。即使在今天,例如 Java 9+,某些构建工具在构建Java项目时会打印出“反射访问”警告,即使构建良好,也只是“感觉未准备好”。
• 直到Java 8为止,你几乎都在使用Oracle的JDK构建,并且你不必在乎许可。但是,甲骨文在2019年更改了许可计划,这使Internet疯狂地说“ Java不再免费”了,随之而来的是相当多的混乱。但是,这并不是真正的问题,你可以在本指南的“ Java发行版”部分中进行了解。
• 一些公司有只使用LTS版本的政策,并依赖他们的操作系统供应商来提供这些版本,这需要时间。
总结起来,你会遇到一系列实际问题(升级工具,库,框架)和政治问题。
为什么某些Java版本称为1.X?
9之前的Java版本仅具有不同的命名方案。因此,Java 8也可以称为1.8,Java 5也可以称为1.5,以此类推。当你使用以下版本发出java -version命令时,将得到如下输出:
c:\Program Files\Java\jdk1.8.0_191\bin>java -version
java version "1.8.0_191" (1)
Java(TM) SE Runtime Environment (build 1.8.0_191-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.191-b12, mixed mode)
这简直就是Java8。随着Java 9切换到基于时间的发行版,命名方式也发生了变化,并且Java版本不再以1.x开头。现在,版本号如下所示:
c:\Program Files\Java\jdk11\bin>java -version
openjdk version "11" 2018-09-25 (1)
OpenJDK Runtime Environment 18.9 (build 11+28)
OpenJDK 64-Bit Server VM 18.9 (build 11+28, mixed mode)
Java版本之间有什么区别? 我应该学习特定的吗?
来自其他编程语言,并且版本之间存在重大差异,例如Python 2至3,你可能想知道是否同样适用于Java。
Java在这方面很特殊,因为它向后兼容。这意味着你的Java 5或8程序可以保证与Java 8-13虚拟机一起运行-除了一些例外,你现在不必担心。
显然,它反过来没有用,比如说你的程序依赖Java 8功能,而Java 13功能在Java 8 JVM下根本不可用。
这意味着两件事:
• 你不仅可以“学习”特定的Java版本,例如Java 12。
• 相反,你将在Java 8之前的所有语言功能中都有良好的基础。
• 然后,你可以从像这样的指南中了解Java 9-13附带了哪些附加功能,并尽可能使用它们。
Java版本之间这些新功能的示例是什么?
看看下面的“ Java功能8-13”部分。
但根据经验:较旧,较长的发行周期(3-5年,直到Java 8)意味着每个发行版都有许多新功能。
六个月的发布周期意味着每个版本的功能会更少,因此你可以快速掌握Java 9-13语言功能。
JRE和JDK有什么区别?
到目前为止,我们仅谈论“ Java”。但是Java到底是什么?
首先,你需要区分JRE(Java运行时环境)和JDK(Java开发工具包)。
从历史上看,如果你只对运行Java程序感兴趣,则仅下载JRE。 JRE除其他外包括Java虚拟机(JVM)和“ java”命令行工具。
要开发新的Java程序,你需要下载JDK。 JDK包括JRE拥有的所有内容,以及编译器javac和其他几个工具,例如javadoc(Java文档生成器)和jdb(Java Debugger)。
现在我为什么要用过去时说话呢?
直到Java 8为止,Oracle网站都将JRE和JDK作为单独的下载提供,尽管JDK始终始终在单独的文件夹中包含JRE。对于Java 9,这种区别基本上已经消失了,你总是在下载JDK。 JDK的目录结构也已更改,不再具有显式的JRE文件夹。
因此,即使某些发行版(请参阅“ Java发行版”部分)仍提供单独的JRE下载,似乎也存在仅提供JDK的趋势。因此,从现在开始,我们将交替使用Java和JDK。
然后如何安装Java或JDK?
目前,请忽略Java-Docker映像,.msi包装器或特定于平台的软件包。最后,Java只是一个.zip文件。仅此而已。
因此,将Java安装到计算机上所需要做的就是解压缩jdk- {5-13} .zip文件。你甚至不需要管理员权限。
你解压缩后的Java文件如下所示:
Directory C:\dev\jdk-11
12.11.2019 19:24 <DIR> .
12.11.2019 19:24 <DIR> ..
12.11.2019 19:23 <DIR> bin
12.11.2019 19:23 <DIR> conf
12.11.2019 19:24 <DIR> include
12.11.2019 19:24 <DIR> jmods
22.08.2018 19:18 <DIR> legal
12.11.2019 19:24 <DIR> lib
12.11.2019 19:23 1.238 release
神奇的事情发生在/ bin目录下,在Windows下看起来像这样:
Directory C:\dev\jdk-11\bin
...
12.11.2019 19:23 272.736 java.exe
...
12.11.2019 19:23 20.832 javac.exe
...
因此,你所需要做的就是解压缩该文件并将/ bin目录放在PATH变量中,以便可以从任何地方调用“ java”命令。
(如果你想知道,GUI安装程序(例如来自Oracle或AdoptOpenJDK的GUI安装程序)将为你解压缩并修改PATH变量。
要验证你是否正确安装了Java,则只需运行java -version。如果输出看起来像下面的输出,那就好了!
openjdk version "11" 2018-09-25
OpenJDK Runtime Environment 18.9 (build 11+28)
OpenJDK 64-Bit Server VM 18.9 (build 11+28, mixed mode)
现在,还有一个问题:你从哪里获得Java .zip文件?这将我们带到了发行主题。
Java发行版
有各种各样的网站提供Java下载(阅读:JDK),目前尚不清楚“谁提供什么许可以及哪种许可”。本节将对此有所启发。
OpenJDK项目
就Java源代码而言(请阅读:JRE / JDK的源代码),OpenJDK项目站点上只有一个。
这只是源代码,而不是可分发的内部版本(请考虑:你的.zip文件以及针对特定操作系统的已编译Java命令)。从理论上讲,你和我可以从该源代码生成一个内部版本,将其命名为MarcoJDK,然后开始进行分发。但是我们的发行版将缺乏认证,无法合法地称自己为Java SE兼容。
因此,实际上,有少数供应商实际创建了这些内部版本,并通过了认证(请参阅TCK),然后进行分发。
而且,尽管供应商无法在生成新的Java构建之前从String类中删除方法,但他们可以添加商标(是!)或添加他们认为有用的其他实用程序(例如CLI)。但是除此之外,所有Java发行版的原始源代码都是相同的。
OpenJDK构建(由Oracle)和OracleJDK构建
从源代码构建Java的供应商之一是Oracle。这导致了两个不同的Java发行版,一开始可能会非常混乱。
- OpenJDK由Oracle(!)构建。这些版本是免费的且没有商标,但是Oracle不会在Java 14推出后立即发布Java 13等旧版本的更新。
- OracleJDK,这是一个品牌的商业版本,从2019年更改许可证开始。这意味着它可以在开发期间免费使用,但是如果在生产环境中使用Oracle,则需要付费。为此,你将获得更长的支持,即,如果JVM发疯,则可以更新版本和电话号码。
现在,从历史上讲(Java 8之前的版本),OpenJDK构建和OracleJDK构建之间存在实际的源差异,你可以说OracleJDK是“更好”的。但是到今天为止,这两个版本基本上是相同的,只是有微小的差异。
然后归结为你想要安装的Java版本的付费商业支持(电话号码)。
AdoptOpenJDK
2017年,一组Java用户组成员,开发人员和供应商(亚马逊,微软,Pivotal,Red Hat等)创建了一个名为AdoptOpenJDK的社区。
它们提供了免费的,坚如磐石的OpenJDK构建,具有更高的可用性/更新,甚至为你提供了两种不同的Java虚拟机的选择:HotSpot和OpenJ9。
我强烈建议你如果要安装Java。
Azul Zulu, Amazon Corretto, SAPMachine
你可以在OpenJDK Wikipedia站点上找到OpenJDK构建的完整列表。 其中包括Azul Zulu,Amazon Corretto和SapMachine等。 简而言之,归结为你拥有不同的支持选项/维护保证。
但是,请务必查看各个网站,以了解每种发行版本的优势。
建议
要从头开始重申,除非你有非常特殊的要求,否则请在2019年从https://adoptopenjdk.net获取jdk.zip(.tar.gz / .msi / .pkg)文件或选择提供的软件包 由你的操作系统供应商提供。
Java 功能8-13
如本指南开头所述:基本上,所有8(现在不要挑剔)Java 8语言功能都可以在Java 13中使用。两者之间的所有其他Java版本也是如此。
反过来,这意味着Java 8的所有语言功能都可以作为良好的Java基础知识,而其他所有功能(Java 9-13)则是在该基准之上的许多附加功能。
以下是提供特定版本的简要概述:
Java 8
Java 8是一个庞大的版本,你可以在Oracle网站上找到所有功能的列表。我想在这里提及两个主要功能:
语言功能:Lambdas等
在Java 8之前,无论何时要实例化一个新的Runnable,都必须编写一个匿名内部类,如下所示:
Runnable runnable = new Runnable(){
@Override
public void run(){
System.out.println("Hello world !");
}
};
对于lambda,相同的代码如下所示:
Runnable runnable = () -> System.out.println("Hello world two!");
你还获得了方法参考,重复注释,接口的默认方法以及其他一些语言功能。
Collections & Streams
在Java 8中,你还获得了集合的函数式操作,也称为Stream API。 一个简单的例子:
List<String> list = Arrays.asList("franz", "ferdinand", "fiel", "vom", "pferd");
现在,在Java 8之前的版本中,你基本上必须编写for循环才能对该列表进行处理。
使用Streams API,你可以执行以下操作:
list.stream()
.filter(name -> name.startsWith("f"))
.map(String::toUpperCase)
.sorted()
.forEach(System.out::println);
Java 9
Java 9也是一个相当大的发行版,其中增加了一些功能:
Collections
Collections有几个新的辅助方法,可以轻松地构造Lists, Sets,Maps。
List<String> list = List.of("one", "two", "three");
Set<String> set = Set.of("one", "two", "three");
Map<String, String> map = Map.of("foo", "one", "bar", "two");
Streams
Streams有一些附加,形式为takeWhile,dropWhile和迭代方法。
Stream<String> stream = Stream.iterate("", s -> s + "s")
.takeWhile(s -> s.length() < 10);
Optionals
Optionals严重错过了ifPresentOrElse方法。
user.ifPresentOrElse(this::displayAccount, this::displayLogin);
Interfaces
Interfaces有私有方法:
public interface MyInterface {
private static void myPrivateMethod(){
System.out.println("Yay, I am private!");
}
}
其他语言功能
还有其他一些改进,例如改进的try-with-resources语句或菱形运算符扩展。
JShell
最后,Java提供了一个Shell,你可以在其中试用简单的命令并立即获得结果。
% jshell
| Welcome to JShell -- Version 9
| For an introduction type: /help intro
jshell> int x = 10
x ==> 10
HTTP客户端
Java 9带来了新HttpClient的初始预览版。直到那时,Java的内置Http支持还只是底层的,你不得不依靠Apache HttpClient或OkHttp之类的第三方库。
使用Java 9,Java有了自己的现代客户端——尽管它处于预览模式,这意味着它可能会在更高版本的Java中更改。
Project Jigsaw: Java模块和多版本jar文件
Java 9获得了Jigsaw Module System,它在某种程度上类似于旧的OSGI规范。 深入了解Jigsaw不在本指南的范围内,但是请查看以前的链接以了解更多信息。
Multi-Release .jar文件使一个.jar文件成为可能,其中包含针对不同JVM版本的不同类。因此,例如,在Java 8与Java 10上运行时,你的程序可以表现不同/具有不同的类。
Java 10
Java 10进行了一些更改,例如垃圾回收等。但是,作为开发人员,你唯一可能真正看到的更改就是引入了var关键字,也称为局部变量类型推断。
Local-Variable Type Inference: var-keyword
// Pre-Java 10
String myName = "Marco";
// With Java 10
var myName = "Marco"
感觉是Java语言,不是吗?但是,它仍然是强类型的,并且仅适用于方法内部的变量。
Java 11
从开发人员的角度来看,Java 11的发行版也较小。
字符串和文件
字符串和文件有几个新方法(此处未列出所有方法):
"Marco".isBlank();
"Mar\nco".lines();
"Marco ".strip();
Path path = Files.writeString(Files.createTempFile("helloworld", ".txt"), "Hi, my name is!");
String s = Files.readString(path);
运行源文件
从Java 10开始,你可以运行Java源文件,而无需先对其进行编译。 迈向脚本编写的一步。
ubuntu@DESKTOP-168M0IF:~$ java MyScript.java
Lambda参数的局部变量类型推断(var)
The header says it all:
(var firstName, var lastName) -> firstName + lastName
HttpClient
来自Java 9的HttpClient的最终非预览版本。
Other Goodies
Flight Recorder, No-Op Garbage Collector, Nashorn-Javascript-Engine deprecated, etc.
Java 12
Java 12有一些新功能和清理功能,但是这里唯一值得一提的是Unicode 11支持和新开关表达式的预览,你将在下一节中看到。
Java 13
你可以在此处找到完整的功能列表,但从本质上来说,你将获得Unicode 12.1支持,以及两个新的或改进的预览功能(将来可能会更改):
切换表达(Preview)
开关表达式现在可以返回一个值。而且,你可以对表达式使用lambda样式的语法,而不会出现直通/突破问题:
旧的switch语句如下所示:
switch(status) {
case SUBSCRIBER:
// code block
break;
case FREE_TRIAL:
// code block
break;
default:
// code block
}
在Java 13中,switch语句如下所示:
boolean result = switch (status) {
case SUBSCRIBER -> true;
case FREE_TRIAL -> false;
default -> throw new IllegalArgumentException("something is murky!");
};
多行字符串(Preview)
最终可以在Java中执行此操作:
String htmlBeforeJava13 = "<html>\n" +
" <body>\n" +
" <p>Hello, world</p>\n" +
" </body>\n" +
"</html>\n";
String htmlWithJava13 = """
<html>
<body>
<p>Hello, world</p>
</body>
</html>
""";
Java 14及更高版本
一经发布,便会在这里进行介绍。
总结
到目前为止,你应该对以下几件事有了一个很好的了解:
• 如何安装Java,要获取的版本以及从何处获取(提示:AdoptOpenJDK)。
• Java发行版是什么,存在哪些发行版,有什么区别。
• 特定的Java版本之间有什么区别。
加入Java学习资料交流qq群:907135806和我们一起探讨吧!有想要JVM、Mysql、Tomcat、Spring Boot、Spring Cloud、Zookeeper、Kafka、RabbitMQ、RockerMQ、Redis、ELK、Git等Java学习资料、视频课程和学习路线的童鞋也可以加vx:ddmsiqi 领取啦,共同进步~