• 一文了解 Java 各发行版本及新特性


    一文了解 Java 各发行版本及新特性

    本文帮助您获取Java最新版与安装实用信息,了解Java各发行版(AdoptOpenJdk、OpenJDK、OracleJDK 等)之间差异,对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年发布)上。真心为这些朋友感到难过!

    • 如果决定使用最新的 IDE、框架和构建工具并启动一个全新的项目,可以毫不犹豫使用地Java 11(LTS)或者最新的Java 13。

    • Android开发是一个特殊领域,版本基本上停留在Java 7,提供一部分Java 8支持。当然,您也可以切换到Kotlin编程语言。

    为什么有些公司仍然坚持使用Java 8?

    原因多种多样,下面是其中几个:

    • 构建工具(比如 Maven、Gradle等)以及某些开发库在 Java 8或者更高版本上运行有bug,需要更新。直到今天,一些工具在Java 9+下构建项目时会打印 "reflective access"-warnings。即使生成的结果没问题,也会让人“感觉没有就绪”。

    • 一直到Java 8,使用Oracle JDK都不用关心许可证。但是,Oracle 在2019年改变了许可证方案。互联网上一石激起千层浪。其中很多文章声称“Java不再免费了”,出现了各式各样的困惑。其实这不是问题,接下来的Java 发行版部分会仔细介绍。

    • 有些公司规定只用LTS版本,并且通过操作系统供应商提供发布,这个过程需要一些时间。

    小结一下:实际工作中会遇到一系列问题,诸如工具升级、开发库升级、框架升级,还有公司规定等等。

    为什么Java 8也叫1.8?

    Java 9以前采用了另一套版本命名规则。Java 8可以叫1.8,Java 5也可以叫1.5等。执行“java -version”命令,输出版本信息如下:

    c:Program FilesJavajdk1.8.0_191in>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)

    简而言之就是Java 8。随着Java 9切换为按时间发布新版本,版本命名方案也发生了变化,不再用1.x作为前缀。现在的版本号像下面这样:

    c:Program FilesJavajdk11in>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和Python 3。同样的逻辑是不是Java也适用?

    Java向后兼容,不会出现这种情况。这意味着,除了少数例外,Java 5或Java 8的程序可以在Java 8-13虚拟机上运行。

    当然,反过来则不成立。如果程序用到了Java 13一些特性,而Java 8 JVM根本不具备这些功能,显然无法工作。

    这意味着两点:

    • 不会只是“学习”某个特定版本的Java,比如Java 12。

    • 相反,之前掌握的Java 8功能都为您打下了良好的基础。这是非常好的基础。

    • 接下来,可以从本文这样的指南中学习使用Java 9-13新增功能。

    Java各个版本都有哪些新功能?

    一起了解Java 8-13新特性。

    按照经验:Java版本越早发行周期越长(比如3到5年,一直到Java 8),这意味着每个发行版包含更多新功能。

    6个月的发布周期意味着每个版本包含的新功能要少得多,因此可以快速掌握Java 9-13的新功能。

    JRE和JDK有什么区别?

    目前为止,一直讨论的是“Java”。Java到底是什么?

    首先需要区分JRE和JDK。

    过去,如果运行Java程序,只下载JRE就可以了。JRE包含Java虚拟机(JVM)和“java”命令行工具。

    如果开发Java程序,需要下载一个JDK。JDK除了包含JRE中的所有内容,还提供了javac编译器及一些工具,比如javadoc(Java文档生成器)和jdb(Java Debugger)等。

    为什么要用“过去”这种说法?

    直到Java 8,尽管JDK有一个独立的JRE文件夹,Oracle网站还是把JRE和JDK作为单独文件提供下载。到Java 9这种区别没有了,只有JDK下载。与此同时,JDK的目录结构也变了,不再出现独立的JRE文件夹。

    虽然某些发行版(参见Java发行版章节)仍然可以单独下载JRE,只提供JDK似乎已经成为一种趋势。从现在开始,Java与JDK可以替换使用。

    如何安装Java?

    先不考虑Java-Docker镜像、.msi安装包或者平台特定的软件包。归根到底Java只是一个.zip文件,仅此而已。

    在计算机上安装Java只需要解压缩jdk-{5-13}.zip文件,甚至都不需要管理员权限。

    解压缩后的Java文件如下:

    Directory C:devjdk-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:devjdk-11in
    ...
    12.11.2019 19:23 272.736 java.exe
    ...
    12.11.2019 19:23 20.832 javac.exe
    ...

    因此,唯一需要做的就是解压缩文件,把/bin目录加到PATH变量,以便从任何地方都可以调用“java”命令。

    (Oracle或AdoptOpenJDK提供的图形化安装程会替您执行解压缩和修改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发行版

    有各种网站提供Java下载,但是不清楚“提供的内容以及采用怎样的许可”。本节会对此进行讨论。

    OpenJDK项目

    就源代码而言,只有一套Java源代码,存在OpenJDK项目中。

    但只是源代码,不是发布版本(.zip文件中针对特定操作系统编译好的Java命令)。理论上,您可以从源代码构建一个版本然后发布,把它叫做MarcoJDK好了。但是这个发行版缺少认证,不能对外号称与Java SE兼容。

    这就是为什么一些供应商会自己构建、进行认证(参见TCK)然后发布。

    尽管供应商不能从String类中删除方法,但是可以添加商标或者他们认为有用的其他实用程序(比如CLI)。除此之外,所有Java发行版的源代码都是一样的。

    OpenJDK Build(Oracle提供)与OracleJDK Build

    Oracle是Java供应商之一,这样产生了两种不同的Java发行版,开始可能会觉得非常混乱。

    1. OpenJDK Build(Oracle提供)。这些Build是免费且没有商标的。但是Oracle不会对之前的老版本发布更新,举个例子,在Java 14推出后不会立即发布Java 13更新。

    2. 从2019年更改许可证开始,OracleJDK变成了带商标的商业版。开发期间可以免费使用,但如果在生产环境中使用就需要向Oracle付费。付费后能够享受长期支持,包括新版本升级,如果JVM出现问题可以享受电话支持。

    Java 8之前,OpenJDK和OracleJDK的源代码实际上不一样,可以说OracleJDK“更好”。时至今日,两个版本几乎相同,只有细小差别。

    归结起来,付费的Java商业版为您提供的就是电话支持。

    AdoptOpenJDK

    2017年,一群Java用户组(JUG)成员、开发者和供应商(包括亚马逊、微软、Pivotal、Redhat等)建立了一个社区称作AdoptOpenJDK。

    他们提供免费、稳固的OpenJDK build,可用性与更新周期更长。甚至还有两个不同的Java虚拟机可供选择:HotSpot和OpenJ9。

    如果安装Java,强烈推荐

    Azul Zulu、Amazon Corretto、SAPMachine。

    在OpenJDK Wikipedia网站上可以找OpenJDK build完整的列表。其中包括Azul Zulu、Amazon Corretto以及SapMachine其他版本。为了便于比较,这个列表按照不同的支持选项与维护策略进行了分类。

    要了解每个发行版本的优势,请务必查看各个网站。

    建议

    2019年开始,除非有非常特殊的要求,否则请从https://adoptopenjdk.net获取jdk.zip (.tar.gz/.msi/.pkg)或者从操作系统供应商提供的软件中选择。

    Java 8-13新特性

    正如本文开头提到的:基本上所有Java 8功能都可以在Java 13中使用。两个版本中间所有其它版本也是如此。

    也就是说,Java 8所有功能都可以作为Java基础知识,Java 9-13中增加的可以看作额外的新增功能。

    以下是各版本的功能概括:

    -Java 8-

    Java 8版本功能非常庞大,可以在Oracle网站上找到所有功能列表。不过,这里要提到两个主要功能:

    语言特性:Lambda。

    Java 8之前,如果要实例化比如一个新的Runnable,都必须写一个匿名内部类,像下面这样:

    Runnable runnable = new Runnable(){
    @Override
    public void run(){
    System.out.println("Hello world !");
    }
    };

    使用Lambd等价代码如下:

    Runnable runnable = () -> System.out.println("Hello world two!");

    此外,Java 8还提供了方法引用、重复注解,接口默认方法及其他功能。

    Collection与Stream

    Java 8还为Collection加入了函数式操作,也称为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 8

    限于篇幅,这里只能概括介绍Java 8的Stream、Lambda或Optional方法,

    想要更详细、更全面的了解和练习,可以看一下Java 8核心功能课程。

    -Java 9-

    Java 9也是一个大版本,其中增加了一些功能:

    Collections

    Collections增加了几个新的helper方法,可以很方便地构造List、Set和Map。

    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");

    Stream

    Stream加入了takeWhile、dropWhile、iterate方法提供了额外功能。

    Stream<String> stream = Stream.iterate("", s -> s + "s")
    .takeWhile(s -> s.length() < 10);

    Optionals

    Optionals增加了迫切需要的ifPresentOrElse方法。

    user.ifPresentOrElse(this::displayAccount, this::displayLogin);

    接口

    接口增加了私有方法:

    public interface MyInterface {

    private static void myPrivateMethod(){
    System.out.println("Yay, I am private!");
    }
    }

    其他语言特性

    Java 9还有其他一些改进,例如改进了try-with-resources、菱形运算符扩展等。

    JShell

    最后,Java 9提供了一个shell,可以执行简单的命令并立即返回结果。

    % jshell
    | Welcome to JShell -- Version 9
    | For an introduction type: /help intro

    jshell> int x = 10
    x ==> 10

    HTTPClient

    Java 9提供了HttpClient新的初始预览版。在此之前,Java内置的Http支持还是相当底层,不得不依靠Apache HttpClient或者OkHttp这样的三方库。

    Java 9开始,Java有了更现代的client。虽然还是预览模式,但意味着在新的Java版本中会继续改进。

    Jigsaw项目:Java模块化与多版本jar文件

    Java 9提供了Jigsaw模块系统,有点像过去的OSGI规范。了解更多Jigsaw项目信息可点击链接查看。

    多版本.jar文件让一个.jar文件包含适用于不同JVM版本的class成为可能。例如,程序在Java 8与Java 10上运行时,可以提供不同的class。

    练习Java 9

    同样,这里只是快速浏览Java 9功能,如果需要更详尽的解释和练习,请查看Java 9核心功能课程。

    -Java 10-

    Java 10也进行了一些改变,像垃圾回收等。作为开发人员,唯一可能真正看到的变化就是引入了“var”关键字,也称为局部变量类型推断。

    局部变量类型推断:var关键字

    // Java 10之前的版本

    String myName = "Marco";

    // 使用Java 10

    var myName = "Marco"

    感觉很像Javascript对吧?不过,这里仍然是强类型,而且仅适用于方法内部变量(感谢,dpash再次指出这一点)。

    -Java 11-

    从开发人员的角度来看,Java 11的变化也很小。

    字符串与文件

    字符串与文件加入了一些新方法(此处未列出所有方法):

    "Marco".isBlank();
    "Mar co".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

    Local-Variable Type Inference (var) for lambda parameters

    header信息说明了一切:

    (var firstName, var lastName) -> firstName + lastName

    HttpClient

    HttpClient完成了最终非预览版本。

    其他改变

    Java 10加入了Flight Recorder、无操作垃圾收集器,弃用了Nashorn Javascript引擎等。

    -Java 12-

    Java 12加入了一些新特性和清理功能。这里唯一值得一提的是Unicode 11支持和新的switch表达式预览版,下一节会看到它。

    -Java 13-

    在这里可以找到完整功能列表。Java 13支持Unicode 12.1,加入了两个新的预览功能(未来可能会更改):

    Switch表达式(预览功能)

    switch表达式现在可以返回一个值。而且可以对表达式使用lambda风格的语法,不会出现fall-through/break问题:

    过去的switch语句看起来像下面这样:

    switch(status) {
    case SUBSCRIBER:
    //代码块
    break;
    case FREE_TRIAL:
    //代码块
    break;
    default:
    //代码块
    }

    Java 13中的switch语句:

    boolean result = switch (status) {
    case SUBSCRIBER -> true;
    case FREE_TRIAL -> false;
    default -> throw new IllegalArgumentException("something is murky!");
    };

    多行字符串(预览功能)

    终于可以在Java中执行这样的操作:

    String htmlBeforeJava13 = "<html>
    " +
    " <body> " +
    " <p>Hello, world</p> " +
    " </body> " +
    "</html> ";

    String htmlWithJava13 = """
    <html>
    <body>
    <p>Hello, world</p>
    </body>
    </html>
    """;

    Java 14及更新版本

    新版本一单发布,会在这里进行介绍。到时记得来看哦。

    结语

    到此为止,您应该对以下几件事有了一个很好的了解:

    • 如何安装Java、选择哪个版本以及从哪里下载(提示:AdoptOpenJDK)。

    • Java发行版是什么、有哪些选择、各自有什么区别。

    • Java各个版本之间有什么区别。

    欢迎反馈、更正和建议!请在下方评论。

    感谢阅读。

    致谢

    关于Java发行版及区别,Stephen Colebourne写了一篇很棒的文章。

  • 相关阅读:
    linux下动态链接库.so文件 静态链接库.a文件创建及使用
    matlab 自动阈值白平衡算法 程序可编译实现
    C++ 迭代器介绍 [转摘]
    C++ Primer 第三章 标准库类型vector+迭代器iterator 运算
    matlab灰度变彩色+白平衡算法实现
    我和奇葩的故事之失联第七天
    C++ Primer 第三章 标准库类型string运算
    OpenCV白平衡算法之灰度世界法(消除RGB受光照影响)
    查看网络情况netstat指令与动态监控top指令
    linux服务
  • 原文地址:https://www.cnblogs.com/zkwarrior/p/13445941.html
Copyright © 2020-2023  润新知