侧边栏壁纸
博主头像
ZHD的小窝博主等级

行动起来,活在当下

  • 累计撰写 79 篇文章
  • 累计创建 53 个标签
  • 累计收到 1 条评论

目 录CONTENT

文章目录

JDK 9 的新特性

江南的风
2017-10-18 / 0 评论 / 0 点赞 / 25 阅读 / 10980 字 / 正在检测是否收录...

Java 9 的新特性(主要特性)

JDK 9(Java Development Kit 9)作为Java平台的一个重要更新,引入了一系列的新特性和改进,旨在提高Java应用程序的开发效率、性能、安全性和模块化。以下是JDK 9的主要新特性:

1. 模块化系统(Project Jigsaw)

  • 模块化系统:JDK 9引入了Java平台模块化系统(JPMS),允许开发者将应用程序分解为多个模块,每个模块都定义了自己的依赖关系和公共API。这有助于减少内存开销,提升性能,并简化依赖管理。

  • 模块声明文件:通过module-info.java文件来声明模块的名称、依赖、导出的包等。

  • jlink工具:JDK 9新增了jlink工具,用于生成自定义的Java运行时映像,只包含应用程序实际需要的模块,从而减少启动时间和内存占用。

例子:假设我们有一个简单的Java项目,该项目包含三个模块:moduleA、moduleB和moduleC。其中,moduleA依赖于moduleB,而moduleB又依赖于moduleC。每个模块都包含一些类和资源,并通过module-info.java文件来定义模块的信息和依赖关系。

目录结构:

MyModularProject/  
|-- modules/  
|   |-- moduleA/  
|   |   |-- src/  
|   |   |   |-- main/  
|   |   |   |   |-- java/  
|   |   |   |   |   |-- com/  
|   |   |   |   |       |-- example/  
|   |   |   |   |           |-- moduleA/  
|   |   |   |   |               |-- ModuleA.java  
|   |   |   |   |-- resources/  
|   |   |-- module-info.java  
|   |-- moduleB/  
|   |   |-- src/  
|   |   |   |-- main/  
|   |   |   |   |-- java/  
|   |   |   |   |   |-- com/  
|   |   |   |   |       |-- example/  
|   |   |   |   |           |-- moduleB/  
|   |   |   |   |               |-- ModuleB.java  
|   |   |   |   |-- resources/  
|   |   |-- module-info.java  
|   |-- moduleC/  
|   |   |-- src/  
|   |   |   |-- main/  
|   |   |   |   |-- java/  
|   |   |   |   |   |-- com/  
|   |   |   |   |       |-- example/  
|   |   |   |   |           |-- moduleC/  
|   |   |   |   |               |-- ModuleC.java  
|   |   |   |   |-- resources/  
|   |   |-- module-info.java  
|-- application/  
|   |-- src/  
|   |   |-- main/  
|   |   |   |-- java/  
|   |   |   |   |-- com/  
|   |   |   |       |-- example/  
|   |   |   |           |-- Application.java  
|   |-- module-info.java (可选,取决于是否将application视为一个单独的模块)  
|-- build/ (或任何用于存放编译后文件的目录)  
|-- bin/ (或任何用于存放可执行文件的目录)  
|-- libs/ (可选,用于存放项目依赖的外部库)  
|-- docs/ (可选,用于存放项目文档)  
|-- .gitignore (或其他版本控制忽略文件)  
|-- build.xml (或其他构建脚本,如Maven的pom.xml或Gradle的build.gradle)  
|-- README.md (项目说明文件)

1. 模块定义

moduleA

  • 包含一个名为com.example.moduleA的包,该包中有一个类ModuleA

  • module-info.java文件定义了模块的依赖关系,即moduleA需要moduleB

// moduleA的module-info.java  
module moduleA {  
    requires moduleB;  
    exports com.example.moduleA;  
}

moduleB

  • 包含一个名为com.example.moduleB的包,该包中有一个类ModuleB

  • module-info.java文件定义了模块的依赖关系,即moduleB需要moduleC,并导出com.example.moduleB包。

// moduleB的module-info.java  
module moduleB {  
    requires moduleC;  
    exports com.example.moduleB;  
}

moduleC

  • 包含一个名为com.example.moduleC的包,该包中有一个类ModuleC

  • module-info.java文件仅导出com.example.moduleC包,不依赖其他模块。

// moduleC的module-info.java  
module moduleC {  
    exports com.example.moduleC;  
}

2. 模块中的类

每个模块中的类都是简单的Java类,例如:

ModuleA.java

package com.example.moduleA;  
  
public class ModuleA {  
    public void doSomething() {  
        System.out.println("Doing something in ModuleA");  
    }  
}

ModuleB.javaModuleC.java 类似,只是包名和类名不同,且可能包含不同的业务逻辑。

3. 使用模块的应用程序

最后,我们创建一个应用程序来使用这些模块。该应用程序将导入moduleAmoduleBmoduleC中的类,并调用它们的方法。

Application.java

import com.example.moduleA.ModuleA;  
import com.example.moduleB.ModuleB;  
import com.example.moduleC.ModuleC;  
  
public class Application {  
    public static void main(String[] args) {  
        ModuleA moduleA = new ModuleA();  
        ModuleB moduleB = new ModuleB();  
        ModuleC moduleC = new ModuleC();  
  
        moduleA.doSomething();  
        moduleB.doSomething(); // 假设ModuleB也有doSomething方法  
        moduleC.doSomething(); // 假设ModuleC也有doSomething方法  
    }  
}

4. 编译和运行

在编译和运行模块化Java应用程序时,需要指定模块路径(--module-path)和主模块(-m)。例如:

javac -d mods/moduleA src/moduleA/module-info.java src/moduleA/com/example/moduleA/ModuleA.java  
javac -d mods/moduleB src/moduleB/module-info.java src/moduleB/com/example/moduleB/ModuleB.java  
javac -d mods/moduleC src/moduleC/module-info.java src/moduleC/com/example/moduleC/ModuleC.java  
javac -d mods/application src/application/Application.java  
  
java --module-path mods -m application/com.example.Application

在上述命令中,mods目录包含编译后的模块,而src目录包含源代码。请注意,实际编译和运行命令可能因项目结构和开发工具的不同而有所差异。

2. JShell

  • 交互式编程环境:JShell是一个交互式Java REPL(Read-Eval-Print Loop)工具,允许用户直接输入Java代码并立即看到结果,无需编译整个程序。这对于学习和测试新的Java特性非常有用。

3. 集合和Stream API的改进

  • 不可变集合的工厂方法:JDK 9新增了一些不可变集合类的工厂方法,使创建不可变集合变得更加方便。

  • Stream API的增强:Stream API中添加了新的方法,如takeWhiledropWhileofNullable以及iterate方法的重载,提供了更多的灵活性和功能。

例如:

// takeWhile ,从头开始筛选,遇到不满足的就结束
List<Integer> list2 = List.of(1, 2, 3, 4, 3, 0);
List<Integer> listResult2 = list2.stream().takeWhile(x -> x < 3).collect(Collectors.toList());
System.out.println(listResult2); // [1, 2]

// dropWhile ,从头开始删除,遇到不满足的就结束
List<Integer> list2 = List.of(1, 2, 3, 4, 3, 0);
List<Integer> listResult2 = list2.stream().dropWhile(x -> x < 3).collect(Collectors.toList());
System.out.println(listResult2); // [3, 4, 3, 0]

// iterate
IntStream.iterate(0, x -> x < 10, x -> x + 1).forEach(System.out::print); // 0123456789

4. 集合工厂方法

在 Java 9 中为集合的创建增加了静态工厂创建方式,也就是 of 方法,通过静态工厂 of 方法创建的集合是只读集合,里面的对象不可改变。并在不能存在 null 值,对于 set 和 map 集合,也不能存在 key 值重复。这样不仅线程安全,而且消耗的内存也更小。

例如:

// 工厂方法创建集合
List<String> stringList = List.of("a", "b", "c", "d");
Set<String> stringSet = Set.of("a", "b", "c", "d");
Map<String, Integer> stringIntegerMap = Map.of("key1", 1, "key2", 2, "key3", 3);

5. 接口支持定义私有方法

Java 8 引入了默认方法,让接口不再仅限于声明,还能包含具体实现。紧接着,Java 9 进一步增加了私有方法,这一改变显著提升了接口的功能性。此举旨在优化代码结构,因为默认方法虽然解决了接口升级时的兼容性问题,但若多个默认方法共享相同逻辑,则不得不重复编写这些代码。有了私有方法后,接口内部可以复用这些逻辑,避免了代码冗余,使得接口设计更加灵活和高效。

例如:

interface Animal {
    void sleep();

    default void eat() {
        drink();
    }

    default void doXxx() {
        drink();
    }

    private void drink() {
        System.out.println("喝水");
    }
}

6. 性能改进

  • JIT编译器的优化:JDK 9中的JIT(Just-In-Time)编译器得到了优化,提供了更快的编译速度和更高的编译效率。

  • G1垃圾收集器的改进:G1垃圾收集器在JDK 9中得到了进一步改进,包括并行全GC的引入、内存回收效率的提升以及延迟的降低。

  • 字符串的优化:JDK 9对字符串的内部表示进行了优化,减少了内存占用和处理时间。

  • 删除 JDK 8 中已弃用的垃圾收集器 (GC) 组合

删除了DefNew + CMS、ParNew + SerialOld、增量CMS组合

  • G1 成为默认垃圾收集器

  • 弃用并发标记扫描 (CMS) 垃圾收集器

弃用并发标记扫描 (CMS) 垃圾收集器。-XX:+UseConcMarkSweepGC使用该选项在命令行上请求时会发出警告消息。Garbage-First (G1) 垃圾收集器旨在替代 CMS 的大多数用途。

7. 其他重要特性

  • 局部变量类型推断(var关键字)(虽然这一特性是在JDK 10中正式引入的,但JDK 9为其奠定了基础):允许开发者在局部变量声明时使用var关键字来替代具体的类型,编译器会根据右侧表达式自动推断出变量的类型。

  • HTTP客户端API:JDK 9新增了HTTP客户端API,为开发者提供了更方便的HTTP客户端功能。

  • 多版本兼容JAR:允许在同一个JAR文件中包含不同版本的类,以便在不同版本的Java环境中运行。

0

评论区