Java SE 16 新增特性
Java SE 16 新增特性
作者:Grey
原文地址:
源码
使用反射执行接口中的默认实现方法
作为对接口中默认方法的增强,随着 Java SE 16 的发布,java.lang.reflect.InvocationHandler
可以通过使用反射调用接口的默认方法。
详见:JDK-8159746
参考如下示例
package git.snippets.jdk16;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import static java.lang.ClassLoader.getSystemClassLoader;
/**
* 反射调用接口的默认方法
*
* @author <a href="mailto:410486047@qq.com">Grey</a>
* @date 2022/8/21
* @since 16
*/
public class InvocationEnhance {
public static void main(String[] args) throws Exception {
invoke();
}
static void invoke() throws Exception {
Object proxy = Proxy.newProxyInstance(getSystemClassLoader(), new Class<?>[]{HelloWorld.class}, (prox, method, args) -> {
if (method.isDefault()) {
return InvocationHandler.invokeDefault(prox, method, args);
}
// ...
return prox;
});
Method method = proxy.getClass().getMethod("hello");
System.out.println(method.invoke(proxy).equals("world"));
}
}
interface HelloWorld {
default String hello() {
return "world";
}
}
运行输出true
。
Sealed Classes 二次预览
Sealed Classes 是在Java SE 15中首次引入的,它提供了一种机制来确定哪些子类被允许扩展或实现父类或接口。在 Java SE 16 中, Sealed Classes 依然是预览状态。
Day Period Support
详见:JDK-8247781
DateTimeFormatter 的一个新成员是日周期符号 "B",它提供了一个上午/下午格式的替代方案。
如下代码:
package git.snippets.jdk16;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
/**
* 详见:https://docs.oracle.com/en/java/javase/16/docs/api/java.base/java/time/format/DateTimeFormatter.html
* @author <a href="mailto:410486047@qq.com">Grey</a>
* @date 2022/8/21
* @since 16
*/
public class DayPeriodTest {
public static void main(String[] args) {
LocalTime date = LocalTime.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("B h:m");
System.out.println(date.format(formatter));
}
}
输出下午 3:54
Stream.toList()
详见:JDK-8180352
其目的是减少一些常用的流收集器的模板代码,如Collectors.toList
和Collectors.toSet
。
示例代码如下
package git.snippets.jdk16;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author <a href="mailto:410486047@qq.com">Grey</a>
* @date 2022/8/21
* @since 16
*/
public class StreamToListMethodDemo {
public static void main(String[] args) {
List<String> integersAsString = Arrays.asList("1", "2", "3");
// before jdk 16
List<Integer> ints = integersAsString.stream().map(Integer::parseInt).collect(Collectors.toList());
// jdk 16+
List<Integer> intsEquivalent = integersAsString.stream().map(Integer::parseInt).toList();
}
}
打包工具增强
使用 jpackage 命令可以把 JAR 包打包成不同操作系统支持的软件格式,
在 Java SE 14 中是预览功能,到Java SE 16中正式启用
常见平台格式如下:
Linux 平台下为deb
和rpm
格式
MacOS 平台下为pkg
和dmg
格式
Windows 平台下为msi
和exe
格式
命令格式为:
jpackage --name myapp --input lib --main-jar main.jar --main-class myapp.Main
要注意的是,jpackage 不支持交叉编译,也就是说在 windows 平台上是不能打包成 MacOS 或者 Linux 系统的软件格式的。
instanceof 模式匹配
在 Java SE 14 中开始作为预览功能,Java SE 16 中被正式启用
package git.snippets.jdk16;
import java.util.ArrayList;
import java.util.Arrays;
/**
* instanceof
*
* @author <a href="mailto:410486047@qq.com">Grey</a>
* @date 2021/11/29
* @since 16
*/
public class InstanceofInJdk16 {
public static void main(String[] args) {
Object o = new ArrayList<String>();
// jdk 16
if (o instanceof ArrayList list) {
list.add("a");
}
// before jdk 16
if (o instanceof ArrayList) {
ArrayList list = (ArrayList) o;
list.add("a");
}
}
}
Records
在 Java SE 15 开始作为预览功能,Java SE 16 正式启用,示例代码如下:
package git.snippets.jdk16;
/**
* Records功能
*
* @author <a href="mailto:410486047@qq.com">Grey</a>
* @date 2021/11/29
* @since 16
*/
public class RecordsInJava15 {
public static void main(String[] args) {
test();
}
// record 是一种全新的类型,它本质上是一个 final 类,
// 同时所有的属性都是 final 修饰,它会自动编译出 public get hashcode 、equals、toString 等方法,减少了代码编写量。
private static void test() {
Cat c1 = new Cat("tomcat", 1);
Cat c3 = new Cat("tomcat", 1);
Cat c2 = new Cat("jerry", 2);
System.out.println(c1);
System.out.println(c2);
System.out.println(c1 == c3);
}
}
record Cat(String name, Integer age) {
}
更多
参考资料
本文来自博客园,作者:Grey Zeng,转载请注明原文链接:https://www.cnblogs.com/greyzeng/p/16611353.html