JDK17初体验
从刚工作时使用的JDK8到现在的JDK17,Java的版本一直在飞速迭代,每个版本都会引入一些新特性和优化改进,比如模块化系统、var类型推断、switch表达式增强、record类、instanceof增强、Sealed类/接口、新的GC等,下面就让我们来体验一下这些新特性吧。
==对于某些不太好测试的特性,这里就忽略了,如模块化系统、ZGC等==
var类型推断
代码
1
2
3
4
5
6
7
8
9
10
11public static void main(String[] args) {
var greeting = "Hello, JDK17";
var num1 = 10;
long num2 = 1000L;
var sum = num1 + num2;
var result = sum % 2 != 0;
System.out.println("greeting: " + greeting);
System.out.println("" + num1 + " + " + num2 + " = " + sum);
System.out.println("result: " + result);
}输出
1
2
3greeting: HELLO, JDK17
10 + 1000 = 1010
result: falseclass文件
可以看到,var只是一种语法糖,编译时会自动转成对应的类型
1
2
3
4
5
6
7
8
9
10public static void main(String[] args) {
String greeting = "Hello, JDK17";
int num1 = 10;
long num2 = 1000L;
long sum = (long)num1 + num2;
boolean result = sum % 2L != 0L;
System.out.println("greeting: " + (String)greeting.transform(String::toUpperCase));
System.out.println("" + num1 + " + " + num2 + " = " + sum);
System.out.println("result: " + result);
}
Http请求客户端
代码
1
2
3
4
5
6
7
8
9
10public static void main(String[] args) throws IOException, InterruptedException {
HttpClient httpClient = HttpClient.newHttpClient();
HttpRequest httpRequest = HttpRequest
.newBuilder()
.uri(URI.create("http://localhost:9090/user/get/202000"))
.build();
HttpResponse<String> httpResponse = httpClient
.send(httpRequest, HttpResponse.BodyHandlers.ofString());
System.out.println("response: " + httpResponse.body());
}输出
1
response: {"data":{"id":1001,"userNo":"10010","nickname":"codecho","mobilePhone":"18755667788","createTime":"2023-03-08 12:04:20","updateTime":"2023-03-08 12:04:20"},"success":true}
switch表达式增强
代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19public static void main(String[] args) {
int month = 4;
System.out.println("month: " + month + ", season: " + getSeason(4));
}
public static String getSeason(int month) {
String season = switch (month) {
case 3, 4, 5 -> "Spring";
case 6, 7, 8 -> "Summer";
case 9, 10, 11 -> "Autumn";
case 12, 1, 2 -> {
System.out.println("month: " + month);
yield "Winter";
}
default -> "illegal month!";
};
return season;
}输出
1
month: 4, season: Spring
class文件
可以看到,switch增强也是语法糖,和普通的switch没什么区别
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36public static void main(String[] args) {
int month = 4;
System.out.println("month: " + month + ", season: " + getSeason(4));
}
public static String getSeason(int month) {
String var10000;
switch (month) {
case 1:
case 2:
case 12:
System.out.println("month: " + month);
var10000 = "Winter";
break;
case 3:
case 4:
case 5:
var10000 = "Spring";
break;
case 6:
case 7:
case 8:
var10000 = "Summer";
break;
case 9:
case 10:
case 11:
var10000 = "Autumn";
break;
default:
var10000 = "illegal month!";
}
String season = var10000;
return season;
}
文本块
代码
1
2
3
4
5
6
7
8
9
10
11
12public static void main(String[] args) {
var text = """
{
"name": "codecho",
"age": 28,
"gender": "male"
}
""";
System.out.println("text block: ");
System.out.println(text);
}输出
1
2
3
4
5
6text block:
{
"name": "codecho",
"age": 28,
"gender": "male"
}class文件
实际还是使用的转换符
1
2
3
4
5public static void main(String[] args) {
String text = "{\n \"name\": \"codecho\",\n \"age\": 28,\n \"gender\": \"male\"\n}\n";
System.out.println("text block: ");
System.out.println(text);
}
record类
代码
1
2
3
4
5
6
7
8public record Boy(String name, int age) {
}
public static void main(String[] args) {
Boy boy = new Boy("Gary", 12);
System.out.println("the boy's name is " + boy.name() + ", he is " + boy.age() + " years old");
}输出
1
the boy's name is Gary, he is 12 years old
反编译class文件
实际继承了Record类(==注意:当前类是final的,不可继承==),编译器自动添加了各个属性方法,和equals、hashCode、toString方法
1
2
3
4
5
6
7
8
9
10
11
12
13public abstract class Record {
protected Record() {}
public abstract boolean equals(Object obj);
public abstract int hashCode();
public abstract String toString();
}
instanceof增强
增强前
1
2
3
4
5
6
7public static void main(String[] args) {
Object o = "instanceof";
if (o instanceof String) {
String str = (String) o;
System.out.println("str: " + str);
}
}增强后
1
2
3
4
5
6public static void main(String[] args) {
Object o = "instanceof";
if (o instanceof String str) {
System.out.println("str: " + str);
}
}
sealed密封类/接口
代码
permit
:指定可以继承的类/接口- sealed`:密封类/接口
no-sealed
:非密封类/接口final
:不可被继承类/接口- 子类继承被
sealed
标记的超类后,同样要求指定密封性,使用sealed
、no-sealed
、final
其中之一指定
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19// MotoVehicle只能由Bus、Car继承
public sealed class MotoVehicle permits Bus, Car {
}
// Bus不能再被继承
public final class Bus extends MotoVehicle {
}
// Car非密封,可以被继承
public non-sealed class Car extends MotoVehicle {
}
// Suv继承Car
public class Suv extends Car {
}作用
使用密封类/接口可以更好地限制类/接口的继承范围,提高代码的安全性和可维护性。