目录
- 引言
- 特性介绍
- 2.1 字符串模版(预览版)
- 2.1.1 在 Java 21 字符串拼接
- 2.1.2 JDK 21 字符串模板
- 2.2 顺序集合*
- 2.2.1 SequencedCollection 接口
- 2.2.2 SequencedSet 和 SequencedMap 类
- 2.3 switch语句的改进
- 2.4 Lambda表达式的新特性
- 2.5 Structural Pattern Matching(结构化模式匹配)
- 2.6 Record(记录)类型的改进
- 2.7 VarHandle的增强**
- 2.8 其他新特性
- 小结
引言
JDK21他来了,于2023年9月19日正式发布。官方传送门有兴趣的同学可以自行查看。
特性介绍
2.1 字符串模版(预览版)
字符串模板(String Templates)的功能,它提供了一种更简洁、更灵活的方式来构建字符串。字符串模板允许在字符串中插入表达式或变量,并在运行时进行求值。通过字符串模版我们代码可读性更强。接下来介绍一下字符串在 JDK 21 以前和之后字符串处理方式。
2.1.1 在 Java 21 字符串拼接
通常通过如下方式
+
号运算符进行拼接这中方式使得代码不容易阅读。- 通过 String::format 或者 String::formatted。
- java.text.MessageFormat。
2.1.2 JDK 21 字符串模板
- 字符串插值新的字符串插值语法允许在字符串中嵌入表达式,使用${expression}的形式。这样可以更方便地将变量或表达式的值嵌入到字符串中,而无需使用字符串连接操作符。例如:
String name = "John"; int age = 25; String message = STR."My name is ${name} and I am ${age} years >old."; System.out.println(message);
输出结果为:My name is John and I am 25 years old.
- 多行模板表达式新的多行模板表达式语法允许在字符串模板中跨多行编写文本。使用三个双引号( “”")将多行文本括起来,可以更清晰地表示多行文本的结构。例如:
String title = "My Web Page"; String text = "Hello, world"; String html = STR."""<html><head><title>\{title}</title></head><body><p>\{text}</p></body></html>""";
输出结果为:
Hello, world
- 字符串模板中使用嵌入的表达式进行计算和自增操作int index = 0;
String data = STR.“{index++}, {index++}, {index++}, {index++}”;
输出结果:“0, 1, 2, 3”- 字符串模板中使用嵌入的表达式来访问数组元素。
String[] fruit = { “apples”, “oranges”, “peaches” };
String s = STR.“{fruit[0]}, {STR.”{fruit[1]}, {fruit[2]}“}”;输出结果:“apples, oranges, peaches”
到这里字符串模版常用场景介绍完毕,更多详细介绍请参看:https://openjdk.org/jeps/430需要注意的是,字符串模板为预览版 API,这意味着它仍处于开发和改进阶段。预览 API可能会在未来的版本中发生变化,因此在生产环境中使用时需要谨慎。
2.2 顺序集合*
针对元素在集合中具有具体的位次的顺序集合例如:ArrayList、LinkedHashSet、LinkedHashMap 等 。JDK 21 新增了三个接口:SequencedCollection、SequencedSet SequencedMap;
并且为这三个接口提供了一些默认实现类,比如 ArrayList、LinkedList 等。这些接口和类提供了更好的对集合中元素顺序的处理。
2.2.1 SequencedCollection 接口
SequencedCollection 接口继承了 Collection 接口,它主要有两个特性:
- 它拥有一个可以用来获取指定索引处的元素的顺序访问迭代器(即位置参数化),同时,它的所有子类也拥有该特性。
- 它的子类(如 ArrayList 和 LinkedList)中的元素可以通过使用其方法(如 add 和 get)进行访问、删除等操作。
SequencedCollection 接口中定义了一些方法,比如:
get(int index)
: 返回指定索引处的元素。indexOf(Object o)
: 返回第一个匹配到的指定元素的索引,如果未找到则返回-1。lastIndexOf(Object o)
: 返回最后一个匹配到的指定元素的索引,如果未找到则返回-1。remove(int index)
: 移除指定索引处的元素。contains(Object o)
: 如果集合中包含指定的元素,则返回 true。isEmpty()
: 如果集合中没有任何元素,则返回 true。
2.2.2 SequencedSet 和 SequencedMap 类
除了 SequencedCollection 接口之外,JDK 21 还新增了两个类:SequencedSet 和 SequencedMap。它们分别继承了 HashSet 和 HashMap,并增加了相应的接口方法。SequencedSet 中新增的方法有:
add(E e)
: 将指定的元素添加到集合中(可选操作)。remove(Object o)
: 从集合中移除指定的元素(可选操作)。contains(Object o)
: 如果集合中包含指定的元素,则返回 true。isEmpty()
: 如果集合中没有任何元素,则返回 true。iterator()
: 返回一个迭代器,它可以按照集合元素的插入顺序来访问集合中的所有元素。SequencedMap 中新增的方法有:
put(K key, V value)
: 将指定的值与此映射中的指定键相关联(可选操作)。remove(Object key)
: 从映射中移除指定键及其关联值(可选操作)。get(Object key)
: 返回指定键关联的值,如果映射中没有这样的项则返回 null。isEmpty()
: 如果映射中没有任何键值对,则返回 true。keySet()
: 返回一个 set,它包含了映射中的所有键。values()
: 返回一个 collection,它包含了映射中的所有值。
2.3 switch语句的改进
在Java 12中,引入了一个新的switch表达式,它可以更方便地处理null值。这个新的switch表达式被称为"switch增强"。它的基本语法如下:
switch (expression) { case value1 -> result1; case value2 -> result2; case value3 -> result3; ... default -> defaultResult; }
这种新的switch语法可以处理null值,如果某个case的值是null,它不会抛出NullPointerException。相反,它会执行相应的结果部分,然后从switch语句中返回。如果没有一个case匹配,那么会执行default部分(如果存在的话)。
2.4 Lambda表达式的新特性
Lambda表达式在Java 11中引入,它是一种简洁的表示匿名函数的方法。在Java 21中,Lambda表达式得到了进一步的改进,允许使用预览语言特性var。
在Lambda表达式中,类型推断是一个重要的概念。使用var可以大大简化Lambda表达式的类型声明。例如:Function<String, Integer> strLength = (String s) -> s.length();
可以被简化为:
Function<String, Integer> strLength = var s -> s.length();
需要注意的是,var不能用于Lambda表达式的返回类型。例如,下面的代码将产生编译错误:
Function<String, var Integer> strLength = (String s) -> 3; //编译错误
2.5 Structural Pattern Matching(结构化模式匹配)
Java 19引入了JEP 406:Structural Pattern Matching(结构化模式匹配)。这种新的匹配方式可以使用“下画线”忽略模式进行匹配。在之前的版本中,使用一个变量名代表要匹配的模式。在结构化模式匹配中,可以使用下画线“_”来表示忽略某个变量。例如:
if (point != null && _ + _ > 0) { ... } // (x, y) point's coordinates
在这个例子中,第二个“_”表示我们不关心y的值,只关心x的值。只要点不为null,且x + y > 0,那么这个条件就成立。这种写法使得代码更加简洁明了。
2.6 Record(记录)类型的改进
Java 14引入了Record类型,这是一种新的数据封装类型,可以更简洁地表达数据不变的语义。在Java 21中,对Record类型做了一些改进:
- 默认的toString、equals、hashCode和compareTo方法变得更加合理。比如,toString方法会按照字段的顺序输出字段名和字段值,hashCode方法会根据字段的hashCode计算Record的hashCode。
- Record的字段现在可以通过名称进行访问和设置。之前,只能通过位置进行访问和设置,现在可以通过名称进行访问和设置,更加方便。例如:
public record Person(String name, int age) {} Person person = new Person("Tom", 20); System.out.println(person.name); // Output: Tom System.out.println(person.age); // Output: 20
2.7 VarHandle的增强**
VarHandle是Java 9引入的一个用于操作内存的基本工具。在Java 21中,VarHandle得到了进一步的增强,增加了几个新的方法,可以更方便地操作内存。例如,
VarHandle.getAndBitwiseOr
、VarHandle.getAndBitwiseAnd
、VarHandle.getAndBitwiseXor
等方法可以用于对内存中的变量进行位操作。
2.8 其他新特性
- 新的时间日期API:Java 21引入了JEP 398:Temporal API,这个API提供了一套全新的时间日期API,可以更方便地处理时间和日期。
- 更好的集合支持:Java 21引入了JEP 406:Structural Pattern Matching(结构化模式匹配),可以在集合操作中更方便地使用模式匹配。
- 虚拟线程:Java 21引入了JEP 338:Virtual Threads,虚拟线程是一种轻量级的线程,可以提高多线程程序的编写和执行效率。
- 新的性能监控工具:Java 21引入了Java Mission Control(JMC),这是一个新的性能监控工具,可以更详细地了解Java应用的性能情况。
小结
总之新特性还是非常多,但是目前还是以学习了解为主,暂时不建议尝鲜使用在生产环境。
点赞收藏,富婆包养✋✋