引用参考文档链接
写在开头
- 反射核心重新实现,从API的维护成本和性能都有所提升
- 互联网地址解析器可自定义
switch
针对case
覆盖范围和sealed
类的检测进行了加强Finalization
标注弃用,因目前仍默认启用,因此迁移成本暂时无变化,后期该特性正式删除后,迁移的成本估计需要仔细评估。
默认字符集为UTF-8
Java API 默认字符集为UTF-8,除了console I/O
极简web服务器
从官方文档描述,功能基本与nginx重合。并且从Motivation
中得知它的定位主要是校园内的教学场景。
案例
代码demo
1 | /** |
部分注释说明
- @highlight substring=”func”
是将当前行的注释java代码中的func高亮 - // @replace regex=’”.*”‘ replacement=”…”
当前行在作为注释代码时,通过正则匹配,将“hihihi”替换为…
javadoc脚本
1 | javadoc -private -d .../Downloads/test --source-path ".../JavaFeature/JDK18/src/main/java:.../JavaFeature/JDK18/src/main/resources" ".../JavaFeature/JDK18/src/main/java/module-info.java" ".../JavaFeature/JDK18/src/main/java/com/janwarlen/feature/CodeSnippets.java" ".../JavaFeature/JDK18/src/main/java/com/janwarlen/Demo.java" --snippet-path ".../JavaFeature/JDK18/src/main/java/com/janwarlen/feature/" |
参数说明
- –source-path 指明有哪些路径需要参与本次生成
- –snippet-path 标注在使用@snippet 的file文件范围
- -d doc生成文件存放目录,文件较多,建议单独创建空目录
- -private 扫描所有文件
结果简单展示
使用Method Handles重新实现反射核心内容
Method Handles 作为反射的底层机制,重新实现了 java.lang.reflect.Method、Constructor、Field 组件,将大大降低反射 API 的维护和开发成本。
This benefits Project Loom by reducing the use of native stack frames.
Vector API (第三次孵化)
变动内容:
- 支持ARM 标量矢量扩展 (SVE) 平台。
- 在支持硬件掩码的架构上提高接受掩码的向量操作的性能。
互联网地址解析 SPI
为主机名和地址解析定义服务提供者接口 (SPI),以便java.net.InetAddress可以使用平台内置解析器以外的解析器。
在尝试自定义解析器的过程中发现一个难以解决的问题,InetAddress
是通过ServiceLoader.load(InetAddressResolverProvider.class)
去找所有实现的解析器,但是用户自定义的解析器所在的module
不在java.base
的requires
/uses
中,根据模块化的隔离,此时java.base
是看不到自定义实现的解析器的。。。
原因在于如果类在声明了module的工程中,就跳过不load了。。。
1 | java.util.ServiceLoader.LazyClassPathLookupIterator#hasNextService |
当我删除module-info.java
后,自定义的解析器就可以被识别了。
案例
代码
1 | import java.net.Inet4Address; |
1 | import java.net.spi.InetAddressResolver; |
简单调用代码
1 | public static void func() { |
输出结果
1 | classLoader load class:ResolverProvider |
调用本地方法和操作堆外内存(第二次孵化)
本次变更内容:
- 内存访问var句柄中支持更多的载体,如booleanand MemoryAddress;
- 一个更通用的解引用 API,在MemorySegment和MemoryAddress接口中都可用;
- 一个更简单的 API 来获取下调用方法句柄,MethodType不再需要传递参数;
- 一个更简单的 API 来管理资源范围之间的时间依赖关系;和
- 用于将 Java 数组复制到内存段和从内存段复制的新 API。
挖个坑,后续补上代码demo;
switch匹配模式增强(第二次预调整)
变更内容:
- 同类型的case必须所有case都有类型声明(我的理解应该产生了偏差),在该案例中,
CharSequence
的覆盖范围比String
大,因此此处就是有问题的。该变动应该是增强了case之间的条件覆盖范围检查。1
2
3
4
5
6
7
8
9
10
11static void error(Object o) {
switch(o) {
case CharSequence cs ->
System.out.println("A sequence of length " + cs.length());
case String s -> // Error - pattern is dominated by previous pattern
System.out.println("A string: " + s);
default -> {
break;
}
}
} - 对
sealed
进行了拓展支持,当case中出现sealed
相关的类时,会检测其他类是否都已覆盖1
2
3
4
5
6
7
8
9
10
11
12sealed interface S permits A, B, C {}
final class A implements S {}
final class B implements S {}
record C(int i) implements S {} // Implicitly final
static int testSealedExhaustive(S s) {
return switch (s) {
case A a -> 1;
case B b -> 2;
case C c -> 3;
};
}1
2
3
4
5
6
7
8
9
10sealed interface I<T> permits A, B {}
final class A<X> implements I<String> {}
final class B<Y> implements I<Y> {}
static int testGenericSealedExhaustive(I<Integer> i) {
return switch (i) {
// Exhaustive as no A case possible!
case B<Integer> bi -> 42;
}
}
弃用 Finalization
可以先查看迁移到JDK18为何写一个空的finalize()方法?
官方文档共4个角度决定放弃
- 安全漏洞(资源泄漏可通过
try-with-resources
和Cleaners
方式避免) - 性能
- 不可靠的执行
- 困难的编程模型(编码成本较高)
目前仍默认启用,可通过--finalization=disabled
禁用