Java 15 的新特性
1. 密封类(Sealed Classes)(预览特性)
Java 提供了final
关键字来确保一个类既不可被继承也不可修改,这在某些情况下限制了类的灵活性。特别是,当需要控制哪些类可以继承某个类时,final
就显得不够用了,因为它只允许“要么能继承,要么完全不能”的二元选择。为了增加这种控制的灵活性,Java 15 引入了sealed
类的新特性。
使用sealed
修饰的类能够明确指定哪些类可以作为它的子类。这样,该类就只能被这些明确指定的类所继承,从而提供了一种比final
更细粒度的继承控制机制。
此外,sealed
类的机制还具有传递性,意味着任何由sealed
类派生的子类也必须使用final
、sealed
或non-sealed
三个关键字之一来修饰,以确保整个继承体系的透明性和可控性。
例子:
// 定义一个sealed类,指定了可能的子类
public sealed class BaseClass permits SubClass1, SubClass2 {
// 类定义...
}
// SubClass1可以是被允许的继承类之一
public final class SubClass1 extends BaseClass {
// 类定义...
}
// SubClass2同样是被允许的继承类
public non-sealed class SubClass2 extends BaseClass {
// 类定义...
// 注意:non-sealed意味着它可以有其他子类,但这些子类必须也被显式允许
}
// 尝试定义一个未被允许的类继承BaseClass将会导致编译错误
public class UnallowedClass extends BaseClass {
// 这里会编译失败,因为UnallowedClass不是BaseClass中指定的子类
}
2. 隐藏类(Hidden Classes)
隐藏类是不能被其他类的字节码直接使用的类,是为在运行时生成类并通过反射间接使用类的框架使用的。
隐藏类可以定义为访问控制嵌套的成员,并且可以独立于其他类进行卸载。
使用过程:
定义隐藏类:首先,你需要有一个类的字节码。这个字节码可以通过编译Java源代码得到,然后对其进行Base64编码等处理,以便在运行时通过反射加载。
加载隐藏类:使用
MethodHandles.lookup().defineHiddenClass
方法加载隐藏类的字节码。这个方法会返回一个Lookup
对象,你可以通过调用lookupClass
方法获取隐藏类的Class
对象。使用隐藏类:获取到隐藏类的
Class
对象后,就可以像使用普通类一样使用它了,包括调用其中的方法。
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.reflect.Method;
public class HiddenClassExample {
public static void main(String[] args) throws Throwable {
// 假设这里已经有了隐藏类的字节码(经过Base64解码)
byte[] classBytes = ...; // 这里应该是隐藏类的字节码
// 加载隐藏类
Class<?> hiddenClass = MethodHandles.lookup()
.defineHiddenClass(classBytes, true, MethodHandles.Lookup.ClassOption.NESTMATE)
.lookupClass();
// 输出类名
System.out.println(hiddenClass.getName());
// 调用隐藏类中的方法
Method method = hiddenClass.getDeclaredMethod("hello");
method.setAccessible(true);
String result = (String) method.invoke(null); // 假设hello是静态方法
System.out.println(result);
}
// 假设这是隐藏类中的方法
// public static String hello() { return "Hello, Hidden Class!"; }
}
3. 爱德华曲线算法(EdDSA)
爱德华曲线算法(EdDSA,Edwards-curve Digital Signature Algorithm)是一种基于扭曲爱德华兹曲线的数字签名算法,由Daniel J. Bernstein等人在2011年提出。EdDSA使用Schnorr签名的变体,并具备高性能和高安全性。以下是一个关于EdDSA的例子,特别是如何在Java环境中使用EdDSA进行签名和验证的概述。
import java.security.*;
public class EdDSADemo {
public static void main(String[] args) throws Exception {
// 生成密钥对
KeyPairGenerator kpg = KeyPairGenerator.getInstance("Ed25519");
KeyPair kp = kpg.generateKeyPair();
// 待签名的消息
byte[] message = "Hello, EdDSA!".getBytes(StandardCharsets.UTF_8);
// 签名
Signature signer = Signature.getInstance("Ed25519");
signer.initSign(kp.getPrivate());
signer.update(message);
byte[] signature = signer.sign();
// 验证签名
Signature verifier = Signature.getInstance("Ed25519");
verifier.initVerify(kp.getPublic());
verifier.update(message);
boolean isValid = verifier.verify(signature);
System.out.println("Signature is valid: " + isValid);
}
}
4. 其他更新
禁用和废弃偏向锁(Biased Locking)
ZGC: 可扩展低延迟垃圾收集器(正式发布)
文本块(正式发布)
String content = """
{
"name": "",
"age": 18,
"updatetime": "2020-11-13 19:50:09",
}
""";
低停顿时间的垃圾收集器Shenandoah(正式发布):java -XX:+UseShenandoahGC
重新实现 DatagramSocket API
移除 Nashorn JavaScript 引擎
评论区