# Java9新特性

# 集合工厂方法(必备)

# 基本用法

Java9的一个最重要的功能就是集合工厂方法,有一个你创建不可变集合时就不用再那么繁琐了,直接调用of方法

//原始的创建不可变集合的方法
List<Object> list = new ArrayList<>();
        list.add("1");
        list.add("2");
        list.add("3");

//java9的创建不可变集合的方法
List<Object> list1 = List.of("1","2","3");
Set<String> strings = Set.of("1", "2", "3");
Map<String, String> food = Map.of("fruit", "apple", "vegetable", "potato");
1
2
3
4
5
6
7
8
9
10

如果你在不可变集合中想再加一个元素,会报UnsupportedOperationException异常

List<Object> list1 = List.of("1","2","3");
list1.add("4");
1
2

本地图片

如果想创建大量元素的不可变map,可以用ofEntries方法,因为map.of方法如果超过10个元素会自动报错

 Map<String, String> map = Map.ofEntries(
        Map.entry("fruit", "apple"),
        Map.entry("vegetable", "potato")
);
1
2
3
4

# 模块化设计

# 基本概念

模块 (Module):一个独立的代码单元,包含:

  • 代码(包和类);
  • 模块描述文件 module-info.java

模块路径:替代传统的 classpath,用于存放模块(模块化 JAR 或模块目录)。

关键关键字

  • module:定义模块;
  • requires:声明依赖其他模块;
  • exports:对外暴露指定的包(未暴露的包无法被外部访问,实现真正的封装);
  • opens:允许反射访问指定的包(兼容旧代码);
  • provides/uses:服务提供者接口(SPI)的模块化支持。

下面是这些关键字的基本用法

当你使用模块化设计时,可以先创建一个moudle-info.java

我们的第一个指令是requires。此模块指令允许我们声明模块依赖项:

module my.module {
    requires module.name;
}
1
2
3

默认情况下,模块不会向其他模块公开其任何API,如果我们希望他可利用的话,可以用第二个关键字exports导出包名

module my.module {
    exports com.my.package.name;
}
1
2
3

如果我们需要允许私有类型的反射,但不希望所有代码都公开,那么可以使用opens指令公开特定的包。

module my.module {
  opens com.my.package;
}
1
2
3

模块也可以是其他模块可以使用的服务提供者。我们可以使用provides关键字来给其他模块提供服务

module my.module {
    provides MyInterface with MyInterfaceImpl;
}
1
2
3

服务是可以被其他类使用的特定接口或抽象类的实现。我们用uses指定模块使用的服务。

请注意,我们使用的类名是服务的接口或抽象类,而不是实现类

module my.module {
    uses class.name;
}
1
2
3

# 优点

那么模块化设计这么复杂,我们为什么要使用它,主要是有以下优点:

1.性能:jdk被拆解为很多个模块,在加载时只加载实际需要的模块,减少了内存的使用,提高了性能

2.安全:只有exports的包才能被使用,防止API的滥用

# JShell

JShell是Java 9引入的一个交互式工具,在这个工具出现前,我们要测试一小段Java代码,必须创建类和main方法,编译才能运行。

有了JShell,我们可以像python解释器那样使用Java,如下图(个人感觉用处不大)

本地图片

# try-with-resources

try-with-resources是Java9 对资源的一个简要优化,在 Java 7/8 中,资源变量必须在 try() 括号内声明,即使变量已经提前定义,也需要重新声明一次,代码略显冗余。

Java 9 允许直接将有效的最终变量(未被重新赋值的变量)放入 try() 中,无需重新声明,代码更简洁

对比如下

public static void main(String[] args) throws FileNotFoundException {
        // 提前定义资源变量
        BufferedReader reader = new BufferedReader(new FileReader( "D:\\code1\\Algorithm\\src\\main\\java\\test\\test.txt"));
            try (BufferedReader r = reader) { // 重新声明变量 r
                System.out.println(r.readLine());
        } catch (IOException e) {
            e.printStackTrace();
      }
            try (r) { // 直接用
                System.out.println(r.readLine());
            } catch (IOException e) {
            e.printStackTrace();
       }    
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
最近更新: 9/19/2026, 1:27:08 PM
编程NOTE   |