前言
前面的文章,我们对Java9、Java10、Java11、Java12 、Java13、Java14、Java15、Java16 的特性进行了介绍,对应的文章如下
Java9新增特性
Java10新增特性
Java11新增特性
Java12新增特性
Java13新增特性
Java14新增特性
Java15新增特性
Java16新增特性
今天我们来一起看一下Java17这个版本的一些重要信息
版本介绍
Java 17 是 Java 平台的一个新版本,于 2021 年 9 月 14 日发布。这个版本是在 Java 11 之后的下一个主要版本,Java 17 是一个功能丰富的版本,引入了一些新的特性和改进,旨在提高安全性、性能和可维护性。
特性列表
-
默认的加密算法 :Java 17 引入了一组新的默认加密算法,包括 AES-GCM 和 SHA-256。这些算法比以前的默认算法更安全,提供了更好的加密性能。
-
ZGC 和 Sharding 增强 :Java 17 对 ZGC(Z Garbage Collector)进行了改进,增加了对非堆内存的支持,并改进了并行处理能力。此外,Java 17 还引入了堆内存分片的概念,可以将堆内存分成多个片段,以更好地适应不同类型的工作负载。
-
JDK 预编译 :Java 17 引入了 JDK (Java Development Kit) 预编译功能。这个功能可以在开发过程中提前预编译 Java 类,从而加快应用程序的启动速度。
-
外部化配置 :Java 17 引入了外部化配置的特性,允许将配置信息存储在外部文件中,而不是硬编码在应用程序中。这个特性可以让开发人员更容易地管理和维护应用程序的配置。
-
支持 Applet API :Java 17 再次支持 Applet API,这个 API 可以让开发人员在网页中嵌入 Java 应用程序。虽然这个 API 的使用场景已经减少了很多,但对于一些特定的应用场景来说,它仍然是有用的。
-
JDK 17 引入了新的 JIT(Just In Time)编译器 :Graal。这个编译器是由 Oracle 开发的,可以更有效地编译 Java 代码,提高运行时的性能。
-
Java 17 移除了 javah 工具(用于生成 C 语言头文件) : 这个工具已经不再被推荐使用,因为它的功能已经被其他工具所取代。
-
Java 17 引入了新的 API : 提供了 jdk.incubator.vector 来用于矢量计算。这个 API 可以更高效地处理向量化的数据操作。
-
Java 17 引入了 instanceof 的模式匹配转正 : 这个特性可以让开发者更方便地使用 instanceof 运算符进行模式匹配。
-
Java 17 移除了 RMI(Remote Method Invocation) :这个特性已经被废弃,被其他的远程调用技术所取代。
-
Java 17 引入了 sealed 类(密封类) : 这个特性可以让开发者定义不能被继承或者不能被实现的类,从而增加代码的安全性和可维护性。
-
Records(记录) :Java 17引入了记录,这是一种新的数据类语法,可以更方便地创建数据密集型对象。记录会自动生成getter、setter方法和equals()、hashCode()等方法,使得编写简单的POJO类变得更加容易。
-
Text Blocks(文本块):Java 17引入了文本块,这是一种新的字符串语法,可以更方便地处理多行字符串。使用三重引号(“”")可以定义一个文本块,并自动去除首尾的空白字符。
-
Switch Expressions(开关表达式) :Java 17引入了开关表达式,这是一种新的switch语句语法,可以使代码更加简洁和易读。开关表达式使用“switch (expression) { cases }”的语法,其中cases可以是常量、变量或表达式。
代码示例
- 如何使用Java 17中引入的局部类型推断特性:
import java.util.List;
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
List<String> names = new ArrayList<>();
names.add("Alice");
names.add("Bob");
names.add("Charlie");
for (var name : names) {
System.out.println(name);
}
}
}
在上面的代码中,我们使用了局部类型推断特性来定义了一个类型为ArrayList的变量names。在for循环中,我们使用了“var”关键字来定义一个可以自动推断类型的迭代变量name。在循环体中,我们使用System.out.println()函数打印每个name的值。
- Java 17新特性的代码示例:
import java.util.List;
import java.util.ArrayList;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args) {
List<String> names = new ArrayList<>();
names.add("Alice");
names.add("Bob");
names.add("Charlie");
// 使用密封类和switch表达式
switch (names) {
case ArrayList al -> System.out.println("ArrayList: " + al);
case LinkedList ll -> System.out.println("LinkedList: " + ll);
default -> System.out.println("Other List implementation");
}
// 使用记录和文本块
class Person {
String name;
int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{" + "name='" + name + '\'' + ", age=" + age + '}';
}
}
Person alice = new Person("Alice", 30);
Person bob = new Person("Bob", 25);
Person charlie = new Person("Charlie", 35);
List<Person> people = List.of(alice, bob, charlie);
List<Person> filteredPeople = people.stream()
.filter(person -> person.age > 30)
.collect(Collectors.toList());
// 使用模式匹配和instanceof的例子
Object obj = "Hello World";
if (obj instanceof String str) { // instanceof模式匹配,注意这里的语法变化!
System.out.println("String value: " + str);
} else {
System.out.println("Not a String value");
}
}
}
- 密封类和记录的更详细示例代码:
import java.util.List;
import java.util.ArrayList;
import java.util.stream.Collectors;
// 定义一个密封类
sealed class Animal {
String name;
int age;
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Animal{" + "name='" + name + '\'' + ", age=" + age + '}';
}
}
// 定义一个密封子类
final class Dog extends Animal {
String breed;
public Dog(String name, int age, String breed) {
super(name, age);
this.breed = breed;
}
@Override
public String toString() {
return "Dog{" + "name='" + name + '\'' + ", age=" + age + ", breed='" + breed + '\'' + '}';
}
}
// 定义一个密封子类
final class Cat extends Animal {
String color;
public Cat(String name, int age, String color) {
super(name, age);
this.color = color;
}
@Override
public String toString() {
return "Cat{" + "name='" + name + '\'' + ", age=" + age + ", color='" + color + '\'' + '}';
}
}
public class Main {
public static void main(String[] args) {
List<Animal> animals = new ArrayList<>();
animals.add(new Dog("Spot", 5, "Golden Retriever"));
animals.add(new Cat("Fluffy", 3, "White"));
animals.add(new Animal("Elephant", 10)); // 非密封类实例化时不需要显式声明类名,直接使用Animal类即可。
animals.add(new Dog("Rex", 8, "Poodle")); // 同上,可以继续实例化其他密封类的子类。
animals.add(new Cat("Blackie", 5, "Black")); // 同上,可以继续实例化其他密封类的子类。
animals.add(new Animal("Lion", 10)); // 非密封类实例化时不需要显式声明类名,直接使用Animal类即可。
animals.add(new Dog("Spike", 12, "Bulldog")); // 同上,可以继续实例化其他密封类的子类。
animals.add(new Animal("Tiger", 8)); // 非密封类实例化时不需要显式声明类名,直接使用Animal类即可。
animals.add(new Animal("Penguin", 5)); // 非密封类实例化时不需要显式声明类名,直接使用Animal类即可。
animals.add(new Dog("Lucy", 10, "Poodle")); // 同上,可以继续实例化其他密封类的子类。同时也可以看出,密封类不能被子类化,因此Dog和Cat都是Animal的最终子类。
密封类可以限制继承,只能被密封子类继承,不能被非密封类继承。
密封类的实例化必须显式声明类名,而非密封类则不需要。
记录是一种简化数据模型的方式,可以方便地定义和操作具有固定字段的数据结构。
总结
Java 17是Java的一个较新的版本,它有很多新特性和改进,可以提供更好的性能和更丰富的功能。然而,是否适合用于生产环境还需要根据具体情况进行评估。
在生产环境中,稳定性和可靠性是最重要的因素之一。Java 17可能还处于测试阶段,因此建议在生产环境中使用已经经过广泛验证的版本,如Java 8或Java 11。这些版本已经得到了社区的广泛支持和维护,具有更好的稳定性和可靠性。
另外,在选择Java版本时,还需要考虑与现有系统和应用的兼容性问题。如果现有的系统和应用都是基于较旧的Java版本开发的,那么升级到Java 17可能会导致兼容性问题。在这种情况下,建议在生产环境中继续使用与现有系统和应用兼容的Java版本。
总之,Java 17具有很多新特性和改进,但是否适合用于生产环境还需要根据具体情况进行评估。建议在生产环境中使用已经经过广泛验证的Java版本,以确保稳定性和可靠性。
拓展
AES-GCM
AES-GCM是高级加密标准(AES)的一种工作模式,全称是Galois/Counter Mode。它是一种有效的authenticated encryption算法,无需额外的认证算法,AES-GCM自带认证功能,可以同时完成加密和认证。
AES-GCM模式的主要特点有:
- 基于AES算法,使用AES的密码块进行加密操作。
- 使用Galois字段上的乘法进行认证,可以有效防止修改和重放攻击。
- 使用计数器(Counter)来避免在加密相同的明文时产生相同的密文,增强安全性。
- 认证标签长度较短(只有16字节),性能和带宽开销小。
AES-GCM模式是目前比较流行和高效的authenticated encryption算法,已被TLS、IPsec、MACsec等大量安全协议采用,在云计算、物联网和5G等领域有广泛的应用。
SHA-256
SHA-256是一种安全散列算法,它使用哈希函数来生成固定长度的摘要。SHA-256是SHA-2的一种,是专为防止密码破解而设计的。
SHA-256的特点包括:
- 安全性:SHA-256算法具有很高的安全性,可以抵御暴力破解和字典攻击等攻击方式。
- 唯一性:SHA-256算法生成的哈希值是唯一的,对于不同的输入数据,即使是微小的差异,也会产生完全不同的哈希值。
- 不可逆性:SHA-256算法是不可逆的,也就是说,无法从哈希值还原出原始数据。
- 长度固定:SHA-256算法生成的哈希值长度固定为256位,不会因为输入数据的长度而变化。
SHA-256被广泛应用于密码学、数据完整性验证和数字签名等领域。