zjjfly's blog

Java,Clojure,Scala...

0%

学习Java12~17

本文列举了一些从Java12到17的一些比较重要的特性

switch表达式

新的switch表达式:

1
2
3
4
5
var i = switch (args[0]) {
case "a" -> 1;
case "b" -> 2;
default -> 0;
};

可以看出有两个变化:

  • 在匹配成功之后不再需要break来终止继续的匹配
  • 表达式可以直接给变量赋值

文本块

现在,可以使用使用下面的语法声明一个文本块(多行字符串)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
String s = """
<html>
<p>Ciao, hello</p>
</html>""";
Assertions.assertEquals("<html>\n <p>Ciao, hello</p>\n</html>", s);

//可以使用\来防止添加换行符
s = """
1\
2""";
Assertions.assertEquals("12", s);

//可以使用\s来表示空格
s = """
1s
2""";
Assertions.assertEquals("1 \n2", s);

模式匹配

instanceof

1
2
3
4
Object obj = "Hello,World";
if (obj instanceof String s && s.length() > 5) {
System.out.println("string length: " + s.length());
}

如果在if表达式有instanceof的判断,那么这之后的逻辑判断和语句块中可以直接把对象作为instanceof的类型参数的对象,不再需要显式的类型转换。

switch

1
2
3
4
5
6
7
8
Object inputObject = 500L;
String formattedObject = switch (inputObject) {
case Integer i -> String.format("int %d", i);
case Long l -> String.format("long %d", l);
case Double d -> String.format("double %f", d);
case String s -> String.format("String %s", s);
default -> inputObject.toString();
};

17中新加入的预览特性,可以在switch中利用模式匹配来匹配不同类型的对象,实际上和上面的instanceof的模式匹配左右类型,都是为了避免显式的类型转换。因为是预览特性,所以需要在编译和运行的时候加上参数--enable-preview

记录类型

1
2
3
4
5
6
7
8
9
10
11
12
record Person(String name, int age) {
//可以使用下面的语法给默认的构造函数加一些额外的逻辑
Person {
if (age < 0) {
throw new IllegalArgumentException("age must be greater than zero!");
}
}
}
Person person = new Person("foo", 32);
System.out.println("person = " + person);
System.out.println("person.name() = " + person.name());
System.out.println("person.age() = " + person.age());

类似Scala的case class,在类名后直接跟默认的构造函数参数,这些参数也是这个类的字段,且是不可变的。编译器还会添加访问字段的方法和默认的toString,equals,hasCode等方法。

sealed class

sealed class表示这个类只能有某些指定的子类,未被批准的子类是不允许的。

1
2
3
4
5
public sealed class LineShape permits Rectangle, Square, Triangle {}
public final class Rectangle extends LineShape {}
public non-sealed class Triangle extends LineShape {}
public sealed class Square extends LineShape permits ColorSquare {}
public final class ColorSquare extends Square {}

sealed class的子类必须是final,sealed或者non-sealed修饰的

其他

  • Java17恢复了默认使用严格浮点数,之前的版本需要使用strictfp关键字显式声明
  • 引入了新的随机数生成的接口RandomGenerator,这样可以把API和具体实现分开,并且不改变现有的Random类。