JAVA11和JAVA12再不学就被淘汰了
Posted 开心学编程
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA11和JAVA12再不学就被淘汰了相关的知识,希望对你有一定的参考价值。
JDK11和JDK12已经发布有一段时间了,相信还是有不少小伙伴还在用JDK8和9,可能也有部分小伙伴和我一样已经用上了JDK12,这篇文章的目的并不是为了解读新特性,而是为了方便部分小伙伴学习。
2018年9月26日Java 11 正式发布。这是 Java 大版本周期变化后的第一个长期支持版本,非常值得关注。
先简单介绍一下下面会说到的内容
Java11:
JEP 181: 基于嵌套的访问控制
JEP 309: 动态文件常量
JEP 315: 改进Aarch64内部函数
JEP 318: Epsilon的垃圾收集器
JEP 321: 标准的HTTP客户端
JEP 323: 本地变量Lambda语法
JEP 324: 使用RFC 7748中描述的Curve25519和Curve448实现key
JEP 327: Unicode 10的支持
JEP 328: Flight Recorder
JEP 329: Chacha20和poly1305加密算法
JEP 330: 使用Java文件来启动Java文件
JEP 331: 可伸缩低延迟垃圾收集器
JEP 332: 支持RFC 8446中的TLS 1.3版本
JEP 333: ZGC
Java12:
JER189 低暂停时间的 GC
JEP230 微基准测试套件
JEP325 Switch 表达式
JEP334 JVM 常量 API
JEP340 只保留一个 AArch64 实现
JEP341 默认类数据共享归档文件
JEP344 可中止的 G1 Mixed GC
JEP346 G1 及时返回未使用的已分配内存
JEP 181: 基于嵌套的访问控制
在默认、private、protecte、public的基础上,JVM又提供了一种新的访问控制机制:Nest、
如果你在一个类中嵌套了多个子类,那么子类中可以访问彼此的私有成员。
package com.alphabet.java11;
import java.lang.reflect.Field;
public class NestTest {
public static class A{
void test() throws Exception{
System.err.println("看看我是不是可以");
var b=new B();
b.b=1;
var field=B.class.getDeclaredField("b");
field.setInt(b,2);
}
}
private static class B{
private int b;
}
public static void main(String[] args) throws Exception {
new A().test();
}
}
JEP 309: 动态文件常量
扩展了字节码文件的格式,用来支持新的常量池。
扩展Java类文件格式以支持新的常量池形式 CONSTANT_Dynamic。CONSTANT_Dynamic将委托创建加载到引导方法,就像链接invokedynamic调用站点将链接委托给引导方法一样。
JEP309:动态文件常量
增加一个常量类型
降低开发新形式的可实现类文件约束带来的成本和干扰
示例代码:
package com.alphabet.java11;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
public class DyTest {
public static void main(String[] args) throws Throwable {
MethodHandles.Lookup ml=MethodHandles.lookup();
var mh=ml.findStatic(
DyTest.class, "test", MethodType.methodType(void.class));
mh.invokeExact(args);
}
private static void test() {
System.out.println("表示执行到了test方法");
}
}
JEP 315: 改进Aarch64内部函数
改进现有的字符串和数组函数,并在Aarch64处理器上为java.lang.Math sin、cos和log函数实现新的内联函数
专用的cpu架构可提高应用程序的性能
示例代码:
package com.alphabet.java11;
import java.util.concurrent.TimeUnit;
public class Aarch64 {
public static void Mathjdk11() {
long time=System.nanoTime();
for (int i = 0; i < 1000000; i++) {
Math.sinh(i);
Math.cos(i);
Math.log(i);
}
long endTime=System.nanoTime();
System.out.println(TimeUnit.NANOSECONDS.toMillis(endTime-time)+"豪秒");
}
public static void main(String[] args) {
Mathjdk11();
}
}
JEP 318: Epsilon的垃圾收集器
JDK上对这个特性的描述是: 开发一个处理内存分配但不实现任何实际内存回收机制的GC, 一旦可用堆内存用完, JVM就会退出.
如果有System.gc()调用, 实际上什么也不会发生(这种场景下和-XX:+DisableExplicitGC效果一样), 因为没有内存回收, 这个实现可能会警告用户尝试强制GC是徒劳.
用法 : -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC
示例代码:
package com.alphabet.java11;
import java.util.ArrayList;
public class EpsilonTest {
public static void main(String[] args) {
boolean flag = true;
var list = new ArrayList<>();
long count = 0;
while (flag) {
list.add(new gc());
if (list.size() == 1000000 && count == 0) {
list.clear();
count++;
}
}
System.out.println("程序结束");
}
}
class gc{
int n = (int)(Math.random() * 100);
@Override
public void finalize() {
System.out.println(this + " : " + n + " 完了");
}
}
如果使用选项-XX:+UseEpsilonGC, 程序很快就因为堆空间不足而退出
JEP 321: 标准的HTTP客户端
在JAVA9中就已经引入了HTTPclient,不过一直处于孵化状态,到了JAVA11,HTTPclient api结束了孵化状态,作为一个标准API提高在Java,net,http包中
取代HTTPurlConnection,之前大家估计都是使用的阿帕奇的HTTPclient
示例代码:
package com.alphabet.java11;
import java.io.IOException;
import java.net.URI;
import java.net.URL;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.http.HttpResponse.BodyHandler;
import java.net.http.HttpResponse.BodyHandlers;
import java.util.concurrent.CompletableFuture;
public class HTTPClientTest {
private static void sendGet(String uri) throws Exception {
var client = HttpClient.newHttpClient();
var request=HttpRequest.newBuilder(URI.create(uri)).build();
var BodyHandler=HttpResponse.BodyHandlers.ofString();
var response =client.send(request,BodyHandler);
System.out.println(response.body());
}
private static void sendAsync(String uri) throws Exception {
var client = HttpClient.newHttpClient();
var request=HttpRequest.newBuilder(URI.create(uri)).build();
var bodyHandler=HttpResponse.BodyHandlers.ofString();
var sendAsync=client.sendAsync(request, bodyHandler);
sendAsync.whenComplete((rest,ex)->{
if (ex!=null) ex.printStackTrace();
else
System.out.println(rest.body());
});
}
public static void main(String[] args) throws Exception{
String uri="http://127.0.0.1:8080";
sendGet(uri);
sendAsync(uri);
}
}
JEP323:Lambda参数的本地变量语法
JAVA8的lambda表达式相信很多老哥都知道,我就不提了
允许var在什么隐式的lambda表达式中的形式参数声明的语法与局部变量声明的语法对齐
Java10的var也不提了,因为emmm,Java10东西还不少,够我水一篇文章了。嘻嘻
示例代码:
package com.alphabet.java11;
import java.util.Arrays;
public class LambdaTest {
private static void varLambda() {
var num=Arrays.asList(1,2,3);
num.sort((a,b)->{
if (a.equals(b))
return 0;
else
return a>b?1:-1;
});
num.sort((var a, var b)->{
if (a.equals(b))
return 0;
else
return a>b?1:-1;
});
System.out.println(num);
}
public static void main(String[] args) {
varLambda();
}
}
JEP 324: Curve25519和Curve448的关键协议
从RFC 7748实现加密图形加密算法方案Curve25519和Curve448规范。 可以保证更安全地交换密钥数据。
示例代码:
package com.alphabet.java11;
import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PublicKey;
import java.security.spec.NamedParameterSpec;
import java.security.spec.XECPublicKeySpec;
import javax.crypto.KeyAgreement;
public class RFC7788 {
KeyPairGenerator kpg = KeyPairGenerator.getInstance("XDH");
NamedParameterSpec paramSpec = new NamedParameterSpec("X25519");
kpg.initialize(paramSpec);
KeyPair kp = kpg.generateKeyPair();
KeyFactory kf = KeyFactory.getInstance("XDH");
BigInteger u = ...
XECPublicKeySpec pubSpec = new XECPublicKeySpec(paramSpec, u);
PublicKey pubKey = kf.generatePublic(pubSpec);
KeyAgreement ka = KeyAgreement.getInstance("XDH");
ka.init(kp.getPrivate());
ka.doPhase(pubKey, true);
byte[] secret = ka.generateSecret();
}
JEP327:Unicode10
升级现有的平台API,支持Unicode10
增加了8518个字符, 总计达到了136690个字符. 并且增加了4个脚本.同时还有56个新的emoji表情符号.
JEP 328: Flight Recorder
Flight Recorder工具从应用程序、JVM和操作系统中收集rizhi数据,这些数据可以帮助分析和解决Java应用程序和HotSpot JVM的故障。
JEP 329: Chacha20和poly1305加密算法
根据RFC 7539中的ChaCha20和Poly1305算法实现流加密。取代旧的和不安全的RC4流密码算法。
JEP 330: 使用Java文件来启动Java文件
增强Java启动程序以运行作为单个Java源代码文件提供的程序
在之前的时候有三种方式运行Java程序
1、使用Javac去编译成class文件
2、启动一个jar包中的main方法
3、启动一个模块当中的main方法类
java Javastack.java,Java11一个命令就够了
JEP 331: 可伸缩低延迟垃圾收集器
提供一种低开销的Java堆分配采样方法,得到堆分配的Java对象信息,可通过JVMTI访问。
JEP 332: 支持RFC 8446中的TLS 1.3版本
实现TLS协议1.3版本。(TLS允许客户端和服务端通过互联网以一种防止窃听,篡改以及消息伪造的方式进行通信)。
JEP 333:ZGC
这个知识点,可以说是Java11最重要的,没有之一,这次只会比较简单的提一下,后期会专门发一篇文章详细概述。 学这个之前需要掌握一些知识点,JVM内存、垃圾回收、判断对象是否是垃圾的算法、回收垃圾对象内存的算法,收集器等基本上看过深入了解JAVA虚拟机的就可以了,这方面的相关知识就不提及了。
ZGC,是一个可伸缩的、低延迟的垃圾收集器,主要为了满足如下目标进行设计:
无论开了多大的堆内存,都能保证10ms的jvm停顿
停顿时间不会随着堆的增大而增大(不管多大的堆都能保持在10ms以下)
可支持几百M,甚至几T的堆大小(最大支持4T)
ZGC的特征:
所有阶段几乎并发执行
像G1一样划分Region,但更灵活
和G1一样会做Compacting 压缩
示例代码::
package com.alphabet.java11;
import java.util.ArrayList;
import java.util.List;
public class ZGCTest {
// 用法 : -XX:+UnlockExperimentalVMOptions –XX:+UseZGC, 因为ZGC还处于实验阶段, 所以需要通过JVM参数来解锁这个特性
public static void main(String[] args) {
List<Garbage> list = new ArrayList<>();
boolean flag = true;
int count = 0;
while (flag) {
list.add(new Garbage());
if (count++ % 500 == 0) {
list.clear();
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
JER189 低暂停时间的 GC
新增了一个名为 Shenandoah 的 GC 算法,通过与正在运行的 Java 线程同时进行 evacuation 工作来减少 GC 暂停时间。使用Shenandoah 的暂停时间与堆大小无关,这意味着无论堆是 200MB 还是 200GB,都将具有相同的暂停时间。
JEP230 微基准测试套件
微基准测试,是衡量一小段 Java 代码性能的艺术,如果没有按照正确的方式实现的话,可能会导致不精确和 / 或误导性的结果。要编写正确的微基准测试,需要考虑很多的事情。
Microbenchmark作为常规性能测试的一部分,在JDK源代码中添加一组基础的微基准测试
可以基于JMH轻松测试JDK的性能。
怎么测试我就先不说了,要下一些jar包,我懒得再创建一个maven项目了。
JEP325 Switch 表达式
对switch语句进行了扩展,使其不仅可以作为语句,还可以作为表达式,并且两种写法都可以使用传统的 switch 语法。
示例代码:
package com.alphabet.java12;
import java.util.ArrayList;
import java.util.List;
public class SwithTest {
public static void main(String[] args) {
int count = new Random().nextInt(10);
System.out.println(count);
switch (count) {
case 1,2,3,4,5 -> System.out.println("优秀");
case 6,7,8 -> System.out.println("优良");
case 9,10 -> System.out.println("优秀");
default -> System.out.println("你们是最胖的");
}
}
class SwithTest2{
int count = new Random().nextInt(10);
System.out.println(count);
int result = switch (count) {
case 1,2,3,4,5 -> 0;
case 6,7,8 -> 2;
case 9,10 -> 5;
default -> 0;
};
System.out.println(result);
}
}
JEP341 默认类数据共享归档文件
首先介绍一个东西,CDS,全称class data-sharing,就是通过将一组核心系统类装载到共享内存中,可以在多个JVM中共享这些类。
CDS使用的是一个只读内存映射文件,他包含了核心类的内部表示,并映射到了每个JVM的堆中,这个文件可以是JRE创建,也可以自己创建
JVM在启动的时候会连接到现有的高速缓存或者创建新的高速缓存。
可以通过读取写入或者只读权限去访问高速缓存,可以运行多个jvm访问同一个高速缓存
高速缓存会动态更新
对共享的类,高速缓存的访问权限受限于操作系统许可权和Java的安全许可权。
高速缓存的生存时间
一个系统可以存在多个高速缓存,可以通过名称去指定
JVM一次只能连接到一个高速缓存上
JEP344 可中止的 G1 Mixed GC
G1就不介绍了,相信大部分小伙伴都指定
可中止的 G1 混合 GC
如果混合 GC 的 G1 存在超出暂停目标的可能性,则使其可中止
JEP346 G1 及时返回未使用的已分配内存
增强 G1 GC,在空闲时自动将 Java 堆内存返回给操作系统。为了实现向操作系统返回最大内存量的目标,G1 将在应用程序不活动期间定期执行或触发并发周期以确定整体 Java 堆使用情况。这将导致它自动将 Java 堆的未使用部分返回给操作系统。而在用户控制下,可以可选地执行完整的 GC,以使返回的内存量最大化。
顺便给自己打波小广告,有需要补习的不,低价补习,JAVA基础,框架,实战,部分JDK源码和框架源码分析,JAVA数据结构和算法等等。绝对低价。
好了,先这样吧,睡觉
下次讲JAVA10和Java13
以上是关于JAVA11和JAVA12再不学就被淘汰了的主要内容,如果未能解决你的问题,请参考以下文章
Java 每半年就会更新一次新特性,再不掌握就要落伍了:Java11 的新特性
拜托,都2023年了,再不懂Android Framework底层原理,真要被淘汰了