JDK8-17新特性(第二部分)
目录
switch表达式增强
在Java中,switch语句的增强主要体现在Java 12引入的预览特性(并在Java 14中成为正式特性)中,即所谓的“Switch Expressions”(switch表达式)。这个新特性使得switch语句变得更加灵活和强大,特别是在处理返回值和代码可读性方面。
传统Switch语句
在传统的Java中,switch语句主要用于根据一个表达式的值选择执行多个代码块之一。但是,它有几个限制:
- 它不能直接返回一个值(除非在每个case分支中使用return语句)。
- 它必须被完整地包含在一个代码块中,这可能导致“fall through”问题(即一个case执行后不会自动停止,而是继续执行下一个case,除非显式地使用了break语句)。
Switch Expressions
Switch Expressions解决了上述问题,并提供了一种更简洁、更灵活的方式来处理基于条件分支的返回值。其主要特点包括:
- 返回值:Switch Expressions可以直接返回一个值,这使得它们可以在表达式中使用,而不仅仅是作为语句。
- 箭头(->)语法:每个case分支现在使用箭头(->)来分隔条件和结果,这使得代码更加简洁和易于阅读。
- 默认分支(default):与传统switch语句一样,Switch Expressions也支持default分支来处理所有未明确匹配的情况。
- 覆盖所有情况的编译时检查:如果Switch Expressions的枚举类型或字符串字面量没有为所有可能的值提供case分支,并且没有default分支,则编译器将报错。这有助于避免运行时错误。
示例
假设我们有一个枚举类型Day
,并希望根据枚举值返回对应的字符串描述:
enum Day {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
public class SwitchExample {
public static String dayToString(Day day) {
return switch (day) {
case MONDAY, FRIDAY, SATURDAY, SUNDAY -> "Weekend";
case TUESDAY, WEDNESDAY, THURSDAY -> "Weekday";
default -> throw new IllegalStateException("Unexpected value: " + day);
};
}
public static void main(String[] args) {
System.out.println(dayToString(Day.MONDAY)); // 输出: Weekend
System.out.println(dayToString(Day.WEDNESDAY)); // 输出: Weekday
}
}
在这个例子中,我们使用了Switch Expressions来根据Day
枚举的值返回不同的字符串。每个case分支都使用箭头(->)来分隔条件和结果。此外,我们还添加了一个default分支来处理所有未明确匹配的情况,并抛出一个异常。
总的来说,Switch Expressions是Java中switch语句的一个重要增强,它提供了更简洁、更灵活的方式来处理基于条件分支的返回值。
文本块标准化
17 引入了几项新特性,其中一项较为显著的是对文本块(Text Blocks)的进一步改进和标准化。文本块特性最初在Java 13中作为预览功能引入,并在Java 15中继续作为预览特性,最终在Java 17中成为正式特性。这一特性的引入,主要是为了简化编写多行字符串和格式化字符串的工作。
文本块简介
文本块允许你以更自然的方式编写字符串字面量,特别是对于那些需要跨越多行、包含特殊字符或需要特定格式(如HTML、SQL查询或JSON数据)的字符串。它们通过三重双引号(""")来界定,并自动管理行尾和缩进。
基本用法
在Java 17中,你可以这样使用文本块:
String html = """
<html>
<body>
<h1>Hello, World!</h1>
</body>
</html>
""";
这里,字符串直接按原样保留了格式和换行,而不需要使用\n来手动插入换行符,也不需要担心内部的引号需要转义。
特性与优势
自动格式化:文本块会自动处理字符串中的换行和缩进,使得代码更加清晰易读。
减少转义字符:在文本块中,大多数情况下不需要使用转义字符,如"来表示双引号。
保留格式:特别适合用于编写SQL查询、HTML、JSON等格式化的文本内容。
控制缩进:末尾的空格会被忽略,可以通过最后一个"""之前的空格或制表符来控制输出字符串的前导空白。
注意事项
- 文本块中,如果需要在字符串中表示三个连续的双引号,可以使用三个双引号加一个空格(""" 」)或者在三个双引号后直接跟随换行。
- 虽然文本块在Java 17中成为正式特性,但在团队协作或维护旧项目时,考虑兼容性问题,确认项目环境和团队是否已准备好采用这一新特性。
模式匹配
如果您使用的是Java,那么您之前很有可能会看到其模式匹配。 String#matches(String)
方法在内部使用Pattern
类型,该类型包含更复杂的功能:
通过编译正则表达式来创建Pattern
。 该模式与任何输入字符串匹配,并且可以选择查找捕获组,这些捕获组隔离了字符串数据的某些部分。
该API的用法如下:
Pattern pattern = Pattern.compile( "([\\^\\S]+) is powerful" ); Matcher matcher = pattern.matcher( "Java is powerful" ); System.out.println(matcher.find()); // true System.out.println(matcher.group()); // Java is powerful System.out.println(matcher.group( 1 )); // Java
find()
方法查找模式的下一次出现,该模式与本示例中的整个输入字符串匹配。 group()
方法返回整个捕获组,即与整个模式匹配,或者在使用索引限定时返回单个捕获组。 捕获组索引从1
开始,而不是从0
。
还有一个matches()
方法,其工作方式略有不同:
Pattern pattern = Pattern.compile( "([\\^\\S]+) is powerful" ); Matcher matcher = pattern.matcher( "Our Java is powerful" ); System.out.println(matcher.matches()); // false System.out.println(matcher.find()); // true
matches()
尝试从头到尾将整个输入字符串与模式匹配,而find()
仅尝试在输入字符串中的某个位置查找模式。
另外,提醒一下:请仅将快捷方式String#matches(String)
或Pattern#matches(String, CharSequence)
用于不重复重复的单个匹配调用。 模式编译起来很繁琐,我们应该利用模式类型的不变性,并将其重用于多个匹配项。
局部变量类型判断
局部变量类型判断目的
通过减少与编写 Java 代码相关的形式来提高开发人员的体验,同时维持 Java 对静态类型安全的承诺,允许开发人员忽略局部变量类型的经常不必要的声明。 此功能将允许声明,例如:
var list = new ArrayList<String>(); // 推断类型为: ArrayList<String>
var stream = list.stream(); // 推断类型为: Stream<String>
局部变量类型推断的概述:
对于带有初始化器的局部变量声明、增强 For 循环索引和传统 For 循环中声明的索引变量,允许用保留类型名 var 代替清单类型
标识符 var 不是关键字,而是保留类型名称。 这意味着使用 var 用作变量、方法或包名称的代码不会受到影响; 使用 var 作为类或接口名称的代码则会受到影响(但这些名称在实践中很少见,因为它们违反了通常的命名约定)。
不允许缺少初始化器、声明多个变量、具有额外数组维括号或引用正在初始化的变量的局部变量声明形式。 未经初始化就拒绝局部变量会缩小特性的范围,避免“ 远距离操作 ”推断错误,并且在典型的程序中只排除一小部分局部变量。
“ var ”语法在有参数的lambda表达式使用:
Consumer<String> consumer = (var t) -> System.out.println(t.toLowerCase()+"-world");
consumer ==> $Lambda$15/0x00000008000b1c40@6093dd95
| 已创建 变量 consumer : Consumer<String>
consumer.accept("Hello");
hello-world
标签:Java,17,matcher,Switch,特性,switch,JDK8,字符串
From: https://www.cnblogs.com/BingBing-8888/p/18474864