Java新特性
该笔记根据学习b站视频制作
Java 9
语法变化
在接口中可以写入私有方法,但是只能在接口内部被default调
从Java 9开始,变量不允许使用_来命名
注解变化
@Deprecated注解的变化
该注解用于标识废弃的内容,在jdk9中新增了两个内容
- String since() default “” : 标识是从哪个版本开始废弃的
- boolean forRemoval() default false : 标识该废弃的内容将来是否会移除,true表示会移除
字符串底层变化
在jdk9之前,String底层是用char数组存储的,而在jdk9,改为了用byte数组存储
String中增加了两个成员变量
- COMPACT_STRINGS: 判断是否压缩,默认是true,如果为false不压缩,就使用UTF-16编码
- coder: 用来区分使用的字符编码,分别为LATIN1(0)和UTF16(1)
当Spring字符串存储英文时,一个英文字符会占用一个字节
当Spring字符串存储中文时,一个中文汉字或占用两个字节,一个字节存储低八位(unicode二进制),一个字节存储高八位
当Spring字符串存储中英文混合时,一个英文字符会占用两个字节
模块化
模块是Java9中新增的一个组件,可以简单理解为是package的上级容器,是多个package的集合,一个jar可以有多个module,一个module可以有多个package。从代码结构上看,jar > module > package > class, interface
Java9的模块通过requires和exports关键字,对自身所依赖(requires)的模块和自身暴露(exports)出去的内容(package)进行了声明。本模块只能使用其他模块暴露(exports)出来的内容(package),其他模块也只能使用本模块暴露(exports)出去的内容(package)
模块化的优点
- 精简jvm加载的class类,提升加载速度
- 对包更精细的控制,提高安全
使用案例
创建两个模块,并创建相关的测试类
Cat类
1 | |
Dog类
1 | |
测试类
1 | |
这时我们尝试在测试类中创建Cat类对象和Dog类对象,会发现找不着对象
因为每个模块对外都是封闭的,我们需要把Cat类和Dog类所在的包对外暴露,在Test模块导入develop模块,才能使用Cat类和Dog类
在devlop模块中创建module-info.java文件
在module-info.java文件暴露Cat类和Dog类所在的包
1 | |
在test模块也创建module-info.java文件,然后导入develop模块
1 | |
再次进行测试
通过反射创建Dog类对象,再测试
1 | |
Java 10
局部类型变量推断
定义变量时可以使用var来定义,再通过=右边的数据来推断数据类型
1 | |
var的使用是有限制的,仅适用于局部变量,增强for循环的索引,以及普通for循环的本地变量,他不能用于方法的形参,构造方法形参,方法返回类型等
Java 11
新增:
1 | |
Java 12
升级了Swatch语法
当多个case条件所生产的结果相同时,可以缩写
1 | |
注意: 这个功能在Java 12中是预览功能,在Java 14才正式上线,如果要在Java 12和Java 13中使用要执行下面命令
1 | |
Java 13
升级了Swatch语法,Swatch语句可以有返回值
1 | |
文本块变化
以前输出多行内容时要换行
1 | |
现在可以输出
1 | |
Java 14
instanceof模式匹配
1 | |
友好的空指针提示
1 | |
record
在创建类时可以创建record类型的,这个类型的类可以省略get方法,构造方法,toString方法,hashcode方法,equals方法等方法,在jdk 14中预览增加了record类型,16正式上线
record类型的特点
- 它是一个final类
- 成员变量均为public属性
- 自动实现equals、hashCode、toString函数
1 | |
现在都是用lombok插件来实现这个效果
Java 15
Sealed Classes
密封类和接口,作用是限制一个类可以由哪些之类继承或者实现
- 如果指定模块的话,sealed class和其之类必须在同一个模块下,如果没用指定模块,则需要在同一个包下
- sealed class指定的子类必须直接继承sealed class
- sealed class的子类要用final修饰
- 如果子类也要被继承,则之类也要用sealed修饰
Java 16
包装类构造方法的警告
使用包装类的构造方法在编译时会出现警告,不在建议使用包装类的构造方法,下面代码在javac编译之后会出现警告
锁对象不要使用包装类
会有警告,包装类底层会有缓冲池,如果锁对象使用包装类,可以会造成不同的锁代码块争抢同一个锁对象的情况
新增日期字段
1 | |
传入不同的字符会打印出不同的效果
| Symbol | Meaning | Presentation | Examples |
| G | era | text | AD; Anno Domini; A |
| u | year | year | 2004; 04 |
| y | year-of-era | year | 2004; 04 |
| D | day-of-year | number | 189 |
| M/L | month-of-year | number/text | 7; 07; Jul; July; J |
| d | day-of-month | number | 10 |
| g | modified-julian-day | number | 2451334 |
| Q/q | quarter-of-year | number/text | 3; 03; Q3; 3rd quarter |
| Y | week-based-year | year | 1996; 96 |
| w | week-of-week-based-year | number | 27 |
| W | week-of-month | number | 4 |
| E | day-of-week | text | Tue; Tuesday; T |
| e/c | localized day-of-week | number/text | 2; 02; Tue; Tuesday; T |
| F | day-of-week-in-month | number | 3 |
| a | am-pm-of-day | text | PM |
| B | period-of-day | text | in the morning |
| h | clock-hour-of-am-pm (1-12) | number | 12 |
| K | hour-of-am-pm (0-11) | number | 0 |
| k | clock-hour-of-day (1-24) | number | 24 |
| H | hour-of-day (0-23) | number | 0 |
| m | minute-of-hour | number | 30 |
| s | second-of-minute | number | 55 |
| S | fraction-of-second | fraction | 978 |
| A | milli-of-day | number | 1234 |
| n | nano-of-second | number | 987654321 |
| N | nano-of-day | number | 1234000000 |
| V | time-zone ID | zone-id | America/Los_Angeles; Z; -08:30 |
| v | generic time-zone name | zone-name | Pacific Time; PT |
| z | time-zone name | zone-name | Pacific Standard Time; PST |
| O | localized zone-offset | offset-O | GMT+8; GMT+08:00; UTC-08:00 |
| X | zone-offset ‘Z’ for zero | offset-X | Z; -08; -0830; -08:30; -083015; -08:30:15 |
| x | zone-offset | offset-x | +0000; -08; -0830; -08:30; -083015; -08:30:15 |
| Z | zone-offset | offset-Z | +0000; -0800; -08:00 |
| p | pad next | pad modifier | 1 |
| ‘ | escape for text | delimiter | |
| ‘’ | single quote | literal | ‘ |
| [ | optional section start | ||
| ] | optional section end | ||
| # | reserved for future use | ||
| { | reserved for future use | ||
| } | reserved for future use |
Java 17
Sealed Classes成为正式版
伪随机数发生变化
增加了伪随机数相关的类和接口来让开发者使用stream流进行操作
- 新接口
RandomGenerator:它为所有现有的和新的 PRNG 提供了一个统一的 API。 RandomGenerators 提供名为 ints、longs、doubles、nextBoolean、nextInt、nextLong、nextDouble 和 nextFloat 的方法,以及它们当前的所有参数的变化。从而更容易在应用程序中互换使用各种 PRNG 算法 - 新类
RandomGeneratorFactory
switch语法变化:可以在swatch中减少强转的操作
1 | |
去除了AOT和JIT
Java 18
默认使用UTF-8字符编码
从jdk 18开始,默认使用UTF-8字符编码,可以通过下面的参数修改为其它字符编码
1 | |
被移除的方法
在jdk 18中,标记了Object中的finalize方法,Thread中的stop方法将在未来被移除
@snippet注解
以前在文档注释中写代码需要添加code标签,现在通过@snippet注解可以更方便的将文档注解中的代码展示在api文档中
Java 19
虚拟线程(预览)
它是轻量级线程,可显著减少编写、维护和观察高吞吐量并发应用程序的工作量。 其目标包括以简单的请求线程样式编写的服务器应用程序,使得能够接近最佳的硬件利用率,现有代码能够以最小的更改采用虚拟线程,并启用故障排除、调试和使用现有 JDK 工具分析虚拟线程
外部函数和API
Java 程序可以通过该 API 与 Java 运行时之外的代码和数据进行互操作。通过高效地调用外部函数(即 JVM 之外的代码)和安全地访问外部内存(即不受 JVM 管理的内存),该 API 使 Java 程序能够调用本机库并处理本机数据,而不会像 JNI 那样危险和脆弱
Java 20
作用域值
作用域值(Scoped Values)它可以在线程内和线程间共享不可变的数据,优于线程局部变量,尤其是在使用大量虚拟线程时。
1 | |
作用域值允许在大型程序中的组件之间安全有效地共享数据,而无需求助于方法参数。
Java 21
字符串模板
String Templates(字符串模板) 目前仍然是 JDK 21 中的一个预览功能。
String Templates 提供了一种更简洁、更直观的方式来动态构建字符串。通过使用占位符${},我们可以将变量的值直接嵌入到字符串中,而不需要手动处理。在运行时,Java 编译器会将这些占位符替换为实际的变量值。并且,表达式支持局部变量、静态/非静态字段甚至方法、计算结果等特性。
虚拟线程正式版