本文列举了一些从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 = """ 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类。