首页
Preview

为什么要从Java 8迁移到Java 11/12?

随着Java的快速更新,为了应对新技术创新的速度,在每六个月的发布周期内,会推出新的许可证和长期支持模型。

为什么要从JDK 8升级到JDK 11?

  • 下一个LTS版本(如果你拥有商业许可证)。
  • Oracle不再提供JRE和Server JRE下载,因此自动更新不再可用。
  • Oracle不再提供32位Windows下载。
  • Java Applet、Java Web Start、Java Plugin和Java Control Panel在JDK中不再可用。请参见删除部署堆栈
  • JavaFX不再包含在JDK中。现在可以从https://openjfx.io/单独下载。
  • JAXB和JAX-WS不再与JDK捆绑在一起。请参见删除Java EE和CORBA模块
  • 支持在G1上并行完整垃圾回收。
  • 免费的应用程序类数据共享功能。
  • 免费的低开销飞行记录仪和堆剖析器。
  • 在替代内存设备上分配堆空间。
  • 新的ZGCEpsilon垃圾收集器。
  • 传输层安全性(TLS)1.3。
  • JShell
  • 支持“shebang”Java文件!#!/bin/java
  • 库的弃用和删除
  • API更新

长期支持: Open JDK和Oracle JDK都具有相同的功能。Open JDK是开源的,而Oracle JDK是Java专有许可证。在Java 10之前,可以免费使用Open JDK和Oracle JDK进行生产,但从Java 11开始,只能免费使用Open JDK进行生产,而不能使用Oracle JDK。有关LTS的几个重要点。

  • 每年推出2个Java版本,直到2028年(Java 31)。
  • 每3年推出一次长期支持版本。因此,在Java 8之后,下一个LTS是Java 11。
  • 3年的支持承诺是最低的,而LTS仅适用于Oracle JDK。我们可以购买Java 11的支持超过3年。
  • 所有Open JDK仅有6个月的支持,直到下一个重大版本。因此,要么购买LTS支持,要么每六个月切换版本。

Java 11/12的主要新功能

启动单文件源代码: 如果我要编写Java程序,我们遵循以下步骤。

public class HelloUniverse{
    public static void main(String[] args) {
        System.out.println("Hello Universe");
    }
}Before Java 11:
Compile:$javac HelloUniverse.java
Run:$java HelloUniverse
O/p:Hello UniverseIn Java 11:
Run:$java HelloUniverse.java
O/p:Hello Universe

现在使用单个源,编译器将直接执行_.java_以输出,不会生成_.class_文件。

注意: 此功能仅限于单个源文件。

使用Java进行脚本编写: 使用shebang(“#!”),我们可以开发可执行的javascript并从命令行运行。

./listallfiles#!/usr/bin/java --source 11import java.nio.file.*;public class ListFiles {
public static void main (String ... args) throws Exception
{
Files.walk(Path.get(args[0]))
.forEaach(System.out::println);
 }
}How to Run:
$chmod +x listallfiles
$./listallfiles .  // Here "." is a current directory.

弃用和删除

  • 从JDK中删除了Java EE和CORBA模块。
  • 删除了Thread.destroy()和Thread.stop()方法。
  • 删除了Applets和Java Web Start。

语言和库的改进

  • HttpClient API: 在Java 11中,HTTP Client已替换为java.net.HttpURLConnection。它可以用于请求网络上的HTTP资源。它支持_HTTP/1.1_和_HTTP/2_,同时支持同步和异步编程模型,将请求和响应体处理为反应流,并遵循熟悉的构建器模式。

示例:获取响应正文并将其打印为字符串的GET请求

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
      .uri(URI.create("http://openjdk.java.net/"))
      .build();
client.sendAsync(request, BodyHandlers.ofString())
      .thenApply(HttpResponse::body)
      .thenAccept(System.out::println)
      .join();
  • 库的改进: 在String库中添加了一些方法,例如“repeat”,isBlank(),strip,lines。
  • Lambda表达式的本地变量语法: 在lambda中使用var

Java 11之前: 我们在lambda表达式中使用显式类型。

// Any local variable declaration
List<String> list = new ArrayList<String>();
Stream<String> stream = getStream()// For Lambda Expression.
(String a, String b) -> a.concat(b)

Java 11: 可以在lambda表达式中使用var,而不使用显式类型。

// Any local variable declaration.
var list = new ArrayList<String>();
var stream = getStream();// For Lambda Expression.
(var a, var b) -> a.concat(b)
  • 基于嵌套的访问控制:_nests_允许将嵌套类编译为属于同一封闭类的不同类文件。然后,它们可以访问彼此的私有类,而无需使用_synthetic/bridge_方法。

性能和安全改进

  • 垃圾回收器改进:Java为你管理堆内存。你在虚拟机(JVM)中运行应用程序。当需要时,JVM会为你分配空间,并在不再需要时释放它。垃圾回收器(GC)是为你执行此操作的组件。回收内存涉及具有对性能产生影响的垃圾收集“周期”。
  • G1 GC是Java 9以来的默认垃圾收集器。在Java 11中,增量改进GC比以前提高了60%的性能。
  • Java 11引入了Epsilon和Z垃圾收集器(ZGC),我们可以选择更适合我们应用程序的GC。
  • 安全性改进:TLS 1.3:现在在JDK中实现了TLS 1.3。删除了旧的遗留算法,并且除了消息加密之外,所有握手算法都被加密。

Java 12的变化

JDK 12提供了少量的新功能和API,其中开关表达式对开发人员最为有趣。 G1的用户无疑会欣赏性能改进。

API更新

  1. 在Stream API中使用Collectors.teeing():一种teeing收集器作为静态方法Collectors::teeing被公开。此收集器将其输入转发到两个其他收集器,然后使用函数将它们的结果合并。

teeing(Collector,Collector,BiFunction)接受两个收集器和一个函数来合并它们的结果。每个传递到生成的收集器的元素都由下游收集器处理,然后使用指定的合并函数将它们的结果合并为最终结果。例如,在给定的员工列表中,如果我们想找到工资最高和最低的员工,我们可以使用teeing收集器在一个语句中完成。

public static void main(String[] args) {
    List<Employee> employeeList = Arrays.asList(
            new Employee(1, "A", 100),
            new Employee(2, "B", 200),
            new Employee(3, "C", 300),
            new Employee(4, "D", 400));

    HashMap<String, Employee> result = employeeList.stream().collect(
            Collectors.teeing(
                    Collectors.maxBy(Comparator.comparing(Employee::getSalary)),
                    Collectors.minBy(Comparator.comparing(Employee::getSalary)),
                    (e1, e2) -> {
                        HashMap<String, Employee> map = new HashMap();
                        map.put("MAX", e1.get());
                        map.put("MIN", e2.get());
                        return map;
                    }
            ));

    System.out.println(result);
}
  • **String API变更:**新增了String.indent()String.transform()Files.mismatch(Path, Path)
  • Switch表达式:Java 12增强了Switch表达式的模式匹配。我们不再需要为每个case块定义break语句,而是可以使用箭头语法

旧的Switch表达式:

public String getTextViaBreak(int number) {
        String result = switch (number) {
            case 1:
            case 2:
                break "one or two"; 
            case 3:
                break "three";
            case 4:
            case 5:
            case 6:
                break "four or five or six";
            default:
                break "unknown";
        };
        return result;
    }

新的Switch表达式:

public String getTextViaArrow(int number) {
        String result = switch (number) {
            case 1, 2 -> "one or two";
            case 3 -> "three";
            case 4, 5, 6 -> "four or five or six";
            default -> "unknown";
        };
        return result;
    }Note: Its preview feature and not going to run in your ide directly.
Follow below steps to run.
$javac --enable-preview --release 13 SwitchExpression.java
$ java --ennable-preview SwitchExpression
  • JVM变更
  1. 低停顿时间垃圾收集器(实验性)

RedHat启动了Shenandoah垃圾收集器,以减少GC暂停时间。其思想是与正在运行的Java线程并发运行GC。

  1. 即时从G1返回未使用的已提交内存:从Java 12开始,在应用程序不活动期间,G1将检查Java堆内存并将其返回给操作系统。这是一种预防措施,以节省和使用空闲内存。

  2. Java微基准测试: 是_Java微基准测试工具箱_的缩写。编写基准测试可测量较大应用程序的小部分的性能。

import org.openjdk.jmh.annotations.Benchmark;public class MyBenchmark {
    @Benchmark
    public void testMethod() {
        // This is a demo/sample template for building your JMH benchmarks. Edit as needed.
        // Put your benchmark code here.        int a = 1;
        int b = 2;
        int sum = a + b;
    }
}
  1. 默认CDS档案: 这增强了JDK构建过程,以在64位平台上使用默认类列表生成类数据共享(CDS)存档。目标是提高启动时间。从Java 12开始,默认情况下启用CDS。

结论: 自Java 8以来发生了许多变化:我们每6个月发布一次更新;许可、更新和支持已经改变;我们获取JDK的位置可能已经改变。当然,还有新的语言特性,包括进入Java 9的主要更改。但是现在,由于Java 11已经取代Java 8成为最新的LTS,而且主要的库、框架和构建工具已经采用了最新的Java版本,现在是将应用程序迁移到Java 11或12的好时机。

你可以在这里找到示例GitHub代码。

译自:https://medium.com/testvagrant/migrate-java-8-to-java-11-12-9ab082f335e8

版权声明:本文内容由TeHub注册用户自发贡献,版权归原作者所有,TeHub社区不拥有其著作权,亦不承担相应法律责任。 如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

点赞(0)
收藏(0)
阿波
The minute I see you, I want your clothes gone!

评论(0)

添加评论