JDK17都出了,学点JDK11新特性

2023-02-23,,

JDK8 - 转- JDK11 -转- JDK17

JShell(JDK9开始支持)

G:\dowload\JDK\JDK11\jdk-11.0.2\bin ===> C:\Windows\System32\cmd.exe

var 局部变量的类型推导

var 不可以作用修饰成员变量。注意var不是关键字,仅仅是语法的改进。

int var = 100;//是有效的

var不是关键字,注意var推断的是接收变量的类型,如果接收变量未定义,那么无效且编译不通过!

var a;//不成立,编译不通过,因为无法推断!

JDK1.7开始的:

List list = new ArrayList<>();//左边的泛型依赖右边的泛型

JDK9开始:

var temp = "Hello World" ;

等价于

String temp = "Hello World" ;

var的最主要的用途一般是用于lambda表达式中!
(@NotNull var t,@NotNull var y)->t.eques(y);

JDK11新添加API

集合API增强

创建固定长度的集合

@Test
public void testList() {
String[] tempNumber = {"abc", "def", "ghi", "jkl", "mno", "pqr"};
//以前创建集合
List<String> stringByList01 = new ArrayList<>();
for (int i = 0; i < tempNumber.length; i++) {
stringByList01.add(tempNumber[i]);
}
System.out.println(stringByList01); //第一次进阶
stringByList01 = new ArrayList<>(Arrays.asList(tempNumber));
//注意Arrays.asList返回的也不是util包下的ArrayList,是Arrays内部类名称也为ArrayList,两个不等同,所以不能添加新元素,异常:不支持操作异常
System.out.println(stringByList01); //JDK11 List.of(...)
List<String> stringByList = List.of(tempNumber);
System.out.println(stringByList);
//stringByList.getClass() = > ImmutableCollections$ListN(不可改变的集合),返回的也不是util包下的ArrayList,也是不能添加新元素
}

同理set创建固定集合

@Test
public void tetSet(){
Set<Integer> integers = Set.of(123, 23, 43, 53, 65, 76, 73, 34, 54);
System.out.println(integers);
//注意,如果set的of方法里面有重复元素,直接抛异常
//IllegalArgumentException
integers = Set.of(123, 23, 43, 53, 65, 123, 23, 43, 53);
System.out.println(integers);
}

JDK11对于流的改进

 @Test
public void streamTest() {
//Stream 流处理创建也是可以使用of方法
Stream<String> stream = Stream.of("5", "2", "1", "4");
//排序和打印
stream.sorted(String::compareTo).forEach(System.out::println);
//可以Stream.of(),但是不可以Stream.of(null);是空指针异常 //JDK11的有传入null的流的创建
Stream<Object> objectStream = Stream.ofNullable(null);
System.out.println(objectStream); //JDK11的新方法takeWhile
Stream<Integer> integerStream = Stream.of(2, 4, 6, 7, 8);
//就是遍历判定是否满足条件,满足的放入新的流中,一旦遇到不满足的就即刻终止遍历
Stream<Integer> takeWhile = integerStream.takeWhile(t -> t % 2 == 0);
takeWhile.forEach(x -> System.out.print(x + ",")); System.out.println();
//JDK11的新方法dropWhile
Stream<Integer> dropWhileStream = Stream.of(2, 4, 6, 7, 8);
//就是遍历判定是否满足条件,不满足的丢弃,一旦遇到满足的就将它和他后面的元素丢入新的流中
Stream<Integer> dropWhile = dropWhileStream.dropWhile(t -> t % 2 == 0);
dropWhile.forEach(x -> System.out.print(x + ",")); //JDK8 流的无限流,迭代
Stream<Integer> iterate = Stream.iterate(1, t -> 2 * t + 1);
iterate.limit(10).forEach(x -> System.out.print(x + ",")); //JDK11 解决无限流,迭代:中间有一个条件终止无限流,转化为有限流
Stream<Integer> youxianliu = Stream.iterate(1, t -> t < 1000, t -> 2 * t + 1);
youxianliu.limit(10).forEach(x -> System.out.print(x + ",")); }

String增强API

@Test
public void stringTest() {
//JDK11字符串新增方法
String str = " \t \n";
//判断字符串是否为空白:
boolean blank = str.isBlank();
System.out.println(blank); //JDK11.去除字符串首尾的空白:处理各种语言的空白字符
String strip = str.strip();// 原来的首尾ASCII码小于32的空格去除:str.trim(),
System.out.println(strip); //去除尾部或者首部的空白
String index = str.stripLeading();
String last = str.stripTrailing(); // 判断字符串是否为空白
" ".isBlank(); // true
// 去除首尾空格
" Javastack ".strip(); // "Javastack"
// 去除尾部空格
" Javastack ".stripTrailing(); // " Javastack"
// 去除首部空格
" Javastack ".stripLeading(); // "Javastack "
// 复制字符串
"Java".repeat(3);// "JavaJavaJava"
// 行数统计
"A\nB\nC".lines().count(); // 3 }

Optional增强:Opthonal 也增加了几个非常酷的方法,现在可以很方便的将一个 Optional 转换成一个 Stream, 或者当一个空 Optional 时给它一个替代的。

	//java ~
String res1 = Optional.of( "java ~" ).orElseThrow();
System.out.println(res1); //1
long res2 = Optional.of( "java ~" ).stream().count();
System.out.println(res2); //java ~
Object res3 = Optional.ofNullable( null )
.or( () -> Optional.of( "java ~" ) )
.get();
System.out.println(res3);

输入流增强api:

transferTo,可以用来将数据直接传输到OutputStream,这是在处理原始数据流时非常常见的一种用法。

try {
InputStream inputStream = TestInputStream.class.getClassLoader().getResourceAsStream("test.txt");
var file = new File("/Users/xxx/test2.txt");
try (var outputStream = new FileOutputStream(file)) {
inputStream.transferTo(outputStream);
}
} catch (IOException e) {
e.printStackTrace();
}

HTTP客户端增强api

这是 Java 9 开始引入的一个处理 HTTP 请求的的孵化 HTTP Client API,该 API 支持同步和异步,而在 Java 11 中已经为正式可用状态,你可以在 java.net 包中找到这个 API。

try {
var request = HttpRequest.newBuilder()
.uri( URI.create("http://t.weather.sojson.com/api/weather/city/101020100"))
.GET()
.build(); var client = HttpClient.newHttpClient(); // 同步
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body()); //异步
client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
.thenApply(HttpResponse::body)
.thenAccept(System.out::println)
.join();
} catch (Exception e) {
e.printStackTrace(); }

工作中异常:IOException, InterruptedException, ExecutionException

读写文件

对Files类增加了writeStringreadString两个静态方法,可以直接把String写入文件,或者把整个文件读出为一个String:

Files.writeString(
Path.of("./", "tmp.txt"), // 路径
"hello, jdk11 files api", // 内容
StandardCharsets.UTF_8); // 编码
String s = Files.readString(
Paths.get("./tmp.txt"), // 路径
StandardCharsets.UTF_8); // 编码

JDK11还带来了EpsilonGC,就是什么也不做的GC,以及ZGC,一个几乎可以做到毫秒级暂停的GC。ZGC还处于实验阶段,所以启动它需要命令行参数-XX:+UnlockExperimentalVMOptions -XX:+UseZGC

ZGC

ZGC, 这应该是JDK11最为瞩目的特性, 没有之一. 但是后面带了Experimental, 说明这还不建议用到生产环境。 GC暂停时间不会超过10ms,既能处理几百兆的小堆, 也能处理几个T的大堆(OMG),和G1相比, 应用吞吐能力不会下降超过15%,为未来的GC功能和利用colord指针以及Load barriers优化奠定基础,初始只支持64位系统 ZGC的设计目标是:支持TB级内存容量,暂停时间低(<10ms),对整个程序吞吐量的影响小于15%。 将来还可以扩展实现机制,以支持不少令人兴奋的功能,例如多层堆(即热对象置于DRAM和冷对象置于NVMe闪存),或压缩堆。 GC是java主要优势之一,当GC停顿太长, 就会开始影响应用的响应时间.消除或者减少GC停顿时长, java将对更广泛的应用场景是一个更有吸引力的平台. 此外, 现代系统中可用内存不断增长,用户和程序员希望JVM能够以高效的方式充分利用这些内存, 并且无需长时间的GC暂停时间

用法 : -XX:+UnlockExperimentalVMOptions –XX:+UseZGC, 因为ZGC还处于实验阶段, 所以需要通过JVM参数来解锁这个特性

完全支持Linux容器(包括Docker)

许多运行在Java虚拟机中的应用程序(包括Apache Spark和Kafka等数据服务以及传统的企业应用程序)都可以在Docker容器中运行。但是在Docker容器中运行Java应用程序一直存在一个问题,那就是在容器中运行JVM程序在设置内存大小和CPU使用率后,会导致应用程序的性能下降。这是因为Java应用程序没有意识到它正在容器中运行。随着Java 10的发布,这个问题总算得以解决,JVM现在可以识别由容器控制组(cgroups)设置的约束。可以在容器中使用内存和CPU约束来直接管理Java应用程序,其中包括:

遵守容器中设置的内存限制

在容器中设置可用的CPU

在容器中设置CPU约束

Java 10的这个改进在Docker for Mac、Docker for Windows以及Docker Enterprise Edition等环境均有效。

容器的内存限制

在Java 9之前,JVM无法识别容器使用标志设置的内存限制和CPU限制。而在Java 10中,内存限制会自动被识别并强制执行。Java将服务器类机定义为具有2个CPU和2GB内存,以及默认堆大小为物理内存的1/4。

支持G1上的并行完全垃圾收集对于 G1 GC,相比于JDK 8,升级到JDK 11即可免费享受到:并行的Full GC,快速的CardTable扫描,自适应的堆占用比例调整(IHOP),在并发标记阶段的类型卸载等等。这些都是针对G1的不断增强,其中串行Full GC等甚至是曾经被广泛诟病的短板,你会发现GC配置和调优在JDK11中越来越方便。

JDK17都出了学点JDK11新特性的相关教程结束。

《JDK17都出了,学点JDK11新特性.doc》

下载本文的Word格式文档,以方便收藏与打印。