# 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");
2
3
4
5
6
7
8
9
10
如果你在不可变集合中想再加一个元素,会报UnsupportedOperationException异常
List<Object> list1 = List.of("1","2","3");
list1.add("4");
2

如果想创建大量元素的不可变map,可以用ofEntries方法,因为map.of方法如果超过10个元素会自动报错
Map<String, String> map = Map.ofEntries(
Map.entry("fruit", "apple"),
Map.entry("vegetable", "potato")
);
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;
}
2
3
默认情况下,模块不会向其他模块公开其任何API,如果我们希望他可利用的话,可以用第二个关键字exports导出包名
module my.module {
exports com.my.package.name;
}
2
3
如果我们需要允许私有类型的反射,但不希望所有代码都公开,那么可以使用opens指令公开特定的包。
module my.module {
opens com.my.package;
}
2
3
模块也可以是其他模块可以使用的服务提供者。我们可以使用provides关键字来给其他模块提供服务
module my.module {
provides MyInterface with MyInterfaceImpl;
}
2
3
服务是可以被其他类使用的特定接口或抽象类的实现。我们用uses指定模块使用的服务。
请注意,我们使用的类名是服务的接口或抽象类,而不是实现类:
module my.module {
uses class.name;
}
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();
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14