10分钟了解JDK11新特性
Posted 计算机ISO
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了10分钟了解JDK11新特性相关的知识,希望对你有一定的参考价值。
JDK11新特性
JEP181:基于嵌套的访问控制
摘要:在private、public、protected的基础上,JVM又提供了新的访问控制机制:Nest;
目标:如果你的一个类中嵌套多个字累,那么子类可以访问彼此的私有成员
public class NestAccessExample {
public static class Nest1 {
void test() throws Exception{
Nest2 nest2 = new Nest2();
nest2.id = 1;
Field field = Nest2.class.getDeclaredField("id");
//在JDK11之前,可以设置该私有变量允许为true强行访问,默认false;
// field.setAccessible(true);
field.setInt(nest2, 1000);
}
}
private static class Nest2 {
private int id;
}
public static void main(String[] args) throws Exception {
new Nest1().test();
}
}
当使用jdk8进行反射嵌套访问时,类中私有成员是不能被访问的
特殊处理,对该字段强行允许
JDK11后多了Nest访问权限,类中私有类的成员可以访问
JEP309:动态类文件常量
摘要:增加一个常量类型 - CONSTANT_Dynamic
目的:降低开发新形式的可实现类文件约束带来的成本和干扰
public class DynamicTest {
public static void main(String[] args) throws Throwable {
MethodHandles.Lookup lookup = MethodHandles.lookup();
MethodHandle methodHandle = lookup.findStatic(
DynamicTest.class,"test",
MethodType.methodType(void.class));
methodHandle.invokeExact();
}
private static void test() {
System.out.println("Hello World!");
}
}
JEP315:改进Aarch64内联函数
摘要:改进现有的字符串和数组函数,并在Aarch64处理器上为java.lang.Math sin cos和log函数实现新的内联函数
目标:专用的CPU架构可提高应用程序的性能
public class Aarch64Example {
private static void MathOnJdk11() {
long startTime = System.nanoTime();
for (int i = 0; i < 10000000; ++i) {
Math.sin(i);
Math.cos(i);
Math.log(i);
}
long endTime = System.nanoTime();
System.out.println(TimeUnit.NANOSECONDS.toMillis(endTime - startTime) + "ms");
}
public static void main(String[] args) {
// JDK11运行三次:1259ms、1298ms、1225ms
// JDK8运行三次:8507ms、8451ms、8410ms
MathOnJdk11();
}
}
JEP321:标准HTTP客户端
摘要:在JDK9中就应该引入了HTTPClient,不过一直处于孵化状态,到了JDK11,HTTPClient API结束了孵化状态,作为一个标准的API提供在java.net.http中
目标:取代HttpURLConnection
public class HttpClientExample {
/**
* 通过get
* @param uri
* @throws Exception
*/
private static void syncGet(String uri) throws Exception{
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder().uri(URI.create(uri)).build();
HttpResponse<String> response = client.send(
request,
HttpResponse.BodyHandlers.ofString()
);
System.out.println(response.statusCode());
System.out.println(response.body());
}
/**
* 异步get
* @param uri
* @throws Exception
*/
private static void asyncGet(String uri) throws Exception{
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder().uri(URI.create(uri)).build();
CompletableFuture<HttpResponse<String>> future =
client.sendAsync(request, HttpResponse.BodyHandlers.ofString());
future.whenComplete((resp,ex) -> {
if (ex != null) {
ex.printStackTrace();
} else {
System.out.println(resp.statusCode());
System.out.println(resp.body());
}
}).join();
}
public static void main(String[] args) throws Exception{
String uri = "http://t.weather.sojson.com/api/weather/city/101030100";
// syncGet(uri);
asyncGet(uri);
}
}
JEP323:Lambda参数的本地变量语法
摘要:允许var在声明隐式类型的lambda表达式的形式参数时使用
目标:将隐式类型的lambda表达式中的形式参数声明的语法和局部变量声明的语法对齐
public class LocalVarExample {
private static void lambdaInJava8() {
new Thread(new Runnable(){
@Override
public void run() {
System.out.println("Before java8");
}
}).start();
new Thread(() -> System.out.println("in Java8")).start();
List<String> list = Arrays.asList("java8","jdk8","1.8");
list.forEach(w -> {
System.out.println("lambda in java8");
System.out.println(w);
});
}
/**
* <1>Java10新特性:局部变量类型推断</1>
*
*/
private static void varInJava10() {
int var = 10;
var i = 10;
var str = "java10";
var list1 = new ArrayList<String>();
var map = Map.of(1,"a",2,"b");
for (var entry : map.entrySet()){
System.out.println(entry);
}
}
/**
* <h1>Java11新特性:Lambda表达式可以使用var标志</h1>
* @param
*/
private static void lambdaWithVarInJava11() {
List<Integer> nums = Arrays.asList(8,11,10);
nums.sort((var s1, var s2) -> {
if (s1.equals(s2)) {
return 0;
} else {
return s1 > s2 ? 1 : -1;
}
});
System.out.println(nums);
}
public static void main(String[] args) {
lambdaInJava8();
lambdaWithVarInJava11();
}
}
JEP327:Unicode 10
摘要:升级现有的平台的API,支持Unicode 10http://unicode.org/versions/Unicode10.0.0/
标准。
目标:支持最新版本的Unicode,主要体现在以下类:
java.lang中的Character,String
java.awt.font中的NumericShaper
java.text中的Bidi,BreakIterator,Normalizer
public class Unicode10Example {
public static void main(String[] args) {
System.out.println("\uD83E\uDDDA");
System.out.println("\uD83E\uDDDB");
System.out.println("\uD83E\uDDDD");
System.out.println("\uD83E\uDDDE");
System.out.println("\uD83E\uDDDF");
}
}
JEP330:启动但文件源代码程序
摘要:增强Java启动程序以运行作为单个Java源代码文件提供的程序
目标:使用java HelloWorld.java运行源代码文件
JEP333:可伸缩低延迟垃圾收集器
摘要:Z垃圾收集器,也称为ZGC,是一个可伸缩的低延迟垃圾收集器
目标:(最核心)无论开了多大的堆内存(128G,2T),保证低于10ms的JVM停顿,远胜于前一代的G1
引用计数算法
概念:堆中每个对象都有一个引用计数器,当一个对象被创建并初始化赋值后,该变量计数设置为1,每当一个地方引用它时,计数器值就加1,当引用失效时,计数器就减1,任何引用计数为0的对象可以被当作垃圾收集
优点:引用计数收集器执行简单,判定效率高,交织在程序运行中,堆程序不被长时间打断的实施环境比较有利(OC的内存管理使用该算法)
缺点:难以检测出对象之间的循环引用,同时,引用计数器增加了程序执行的开销,所以Java语言并没有选择这种算法进行垃圾回收
根搜索算法
标记可达对象:JVM中用到的所有现在GC算法在回收前都会先找出所有仍存活的对象,根搜索算法时从离散数学中的图论引入的,程序把所有的引用关系看作一张图。
回收垃圾对象内存的算法
Tracing算法(Tracing Collector)或标记--清除算法
Compacting算法(Compacting Collector)或标记--整理算法
垃圾收集器
Pause Mark Start - 初始停顿标记
Concurrent Mark - 并发标记
Relocate - 移动对象
Remap - 修正指针
所有阶段几乎都是并发执行
像G1一样划分Region,更加灵活
和G1一样会做Compacting-压缩
单代
说明:G1收集器是当今收集器技术发展最前沿的成果,是一款面向服务器端应用的收集器,重复利用多CPU,多核环境。因此它时一款并行和并发收集器,并且它可建立可预测的停顿时间模型
使用:通过JVM参数-XX:+UseG1GC使用G1垃圾回收器
说明:是JVM默认垃圾回收器,使用多线程进行垃圾回收
使用:可用-XX:+UseParallelGC来强制指定,用-XX:ParallelGCThreads=4指定线程数
说明:单线程环境设计,只使用一个单独的线程进行垃圾回收,是client级别默认的GC方式
使用:通过JVM参数 -XX:+UseSerialGC可以使用串型垃圾回收器
串型垃圾收集器(Serial Garbage Collector)
并行垃圾收集器(Parallel Garbage Collector)
G1收集器(G1 Garbage Collector)
ZGC特性
ZGC工作过程
JDK11新API
String
strip :去掉前后的空格,unicode空格
isBlack :字符串为空或者紧包含空格返回true
lines:返回字符串提取的流
repeat :返回字符串重复次数
stripLeading : 去掉前面的空格
stripTrailing : 去掉后面的空格
Files
readString :直接通过路径写文件
writeString :直接通过路径读文件
List
public class StringExample {
public static void main(String[] args) {
String example = "Hello,World!\u3000";
String empty = "\u3000";
String line = "hello\nworld\ngerry\n";
System.out.println("原始example:" + example);
System.out.println("trim:" + example.trim() + "end");
System.out.println("strip:" + example.strip() + "end");
System.out.println("原始empty:" + empty + "end");
System.out.println("trim:" + empty.trim() + "end");
System.out.println("strip:" + empty.strip() + "end");
//isBlack基于unicode识别
System.out.println("isBlank:" + empty.isBlank());
System.out.println("isEmpty:" + empty.isEmpty());
//line
line.lines().forEach(System.out::println);
//repeat
System.out.println("*".repeat(50));
}
}
public class FileExample {
public static void main(String[] args) throws IOException {
String path = "/Users/gerrydeng/Desktop/test.txt";
Files.writeString(Path.of(path),"hello world!hahahhahha", StandardCharsets.UTF_8);
System.out.println(Files.readString(Path.of(path),StandardCharsets.UTF_8));
}
}
public class ListExample {
public static void main(String[] args) {
//of生成不可变数组
List<String> list = List.of("gerry","tom","marry");
System.out.println(list);
String[] oldWay = list.toArray(new String[0]);
String[] newWay = list.toArray(String[]::new);
}
}
JDK11其他特性
JEP318:误操作垃圾收集器
JEP320:移除JavaEE和CORBA模块
JEP324:Curve25519和Curve448算法的密钥协议
JEP328:Flight Recorder
JEP329:ChaCha20和Poly1305算法
JEP331:低开销的Heap Profiling
JEP332:支持TLS 1.3
JEP335:弃用Nashorn和javascript引擎
JEP336:弃用Pack200工具和API
长按识别以下二维码关注我,定期发送资深工程师学习笔记,知识干货,一般网上搜不到哦!码字不容易,转请注出处和二维码。
以上是关于10分钟了解JDK11新特性的主要内容,如果未能解决你的问题,请参考以下文章