JDK8新特性
JDK9新特性
JDK10新特性
JDK11新特性
JDK12新特性
JDK13新特性
JDK14新特性
JDK15新特性
JDK16新特性
JDK17新特性
JDK18新特性
JDK19新特性
JDK20新特性
JDK21新特性
JDK10提供了超过109项新功能特性,并且JDK10的安装不用再额外安装一次jre了,之前JDK9以及之前都需要额外安装一次jre。
JDK10 可以使用 var 进行 局部变量类型推断。
var str = "abc"; // 推断为 字符串类型
var l = 10L; // 推断为long 类型
var flag = true; // 推断为 boolean 类型
var list = new ArrayList<String>(); // 推断为 ArrayList
var stream = list.stream(); // 推断为 Stream
package com.zt.jdk10NewFeatures;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
public class Jdk10NewFeatures {
// 局部变量类型推断
// 1、只针对局部变量
// 2、var是保留类型不是关键字,意味着我们可以用var来定义变量名
// 3、var不容许赋值为null,例如 var x = null; 会报错
public static void main(String[] args) {
var i = 10;
System.out.println(i);// 10
var str = "zt";
System.out.println(str);// zt
var list = new ArrayList<>();
list.add(10);
list.forEach(System.out::println);// 10
var set = new HashSet<>();
set.add(10);
set.forEach(System.out::println);// 10
var map = new HashMap<>();
map.put("JDK10",10);
map.forEach((k,v) -> {
System.out.println("key:" + k + ",value:" + v);// key:JDK10,value:10
});
var user = new User("zt",18);
System.out.println(user);// User{username='zt', age=18}
}
// 内部类User
static class User {
private String username;
private Integer age;
public User() {
}
public User(String username, Integer age) {
this.username = username;
this.age = age;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", age=" + age +
'}';
}
}
}
public class demo01var {
// var x = 10; // 成员变量不能使用var
public static void main(String[] args) {
var a = 1;
var str = "abc";
var flag = true;
var list = new ArrayList<String>();
list.add("aa");
var stream = list.stream();
for (var s : list) {
System.out.println(s);
}
for (var i = 0; i < 10; i++) {
var x = 5;
}
}
}
public class demo01var {
// var x = 10; // 成员变量不能使用var
// 参数不能使用var
// public static void test01(var a) {}
/* 方法返回类型不能使用var
public static var test02() {
return true;
}*/
}
var 并不是一个关键字,可以作为标识符,这意味着可以将一个变量、方法、包名写成 var 。不过一般情况下
不会有人这么写的,因为这本身就违反了普遍的命名规范。
// var 并不是一个关键字,而是一个保留的类型名称,这意味着可以将一个变量、方法、包名写成 `var`。
public static void test03() {
var var = 10; System.out.println("var = " + var);
}
var 声明变量的时候必须赋值、不能用于声明多个变量的情况。
// var 不能用来声明没有赋值的变量、不能用于声明多个变量的情况。
public static void test04() {
// var x = null;
// 不行,推断不出到底是什么类型
int x = 1, y = 2; // 可以
// var m = 1, n = 2; // 不行
}
截图可以看出早期都是配对的。单线程1GB内存以后就效率非常差了。
上面都是基于分代,分代(年轻代、老年代)的严重缺点还是会随着堆内存增加而stw时间增加;所以后面出了分区模型
java -XX:+PrintCommandLineFlags -version ---- 查看默认gc,jdk8的默认是 Parallel Scavenge 和 Parallel Old 这一对 , jdk9默认就是g1了
G1 是设计来作为一种低延时的垃圾回收器。G1收集器还可以进行非常精确地对停顿进行控制。从JDK7开始启用G1垃圾回收器,在JDK9中G1成为默认垃圾回收策略。截止到java 9,G1的Full GC采用的是单线程算法。也就是说G1在发生Full GC时会严重影响性能。
JDK10又对G1进行了提升,G1 引入并行 Full GC算法,在发生Full GC时可以使用多个线程进行并行回收。能为用户提供更好的体验。
JDK10 给 java.util 包下的List、Set、Map新增加了一个静态方法 copyOf 。copyof方法将元素放到一个不可修改的集合并返回,是按照之前集合的迭代顺序拷贝的,元素顺序和之前集合一样。
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
List<Integer> temp = List.copyOf(list);
temp.forEach(System.out::println);// 1 2 3
temp.add(4);// 不能修改,会报错,如下图
}
JDK10给 java.io.ByteArrayOutputStream 新增重载 toString(Charset charset) 方法,通过指定的字符集编码字节,将缓冲区的内容转换为字符串。
通过ByteArrayOutputStream新增的toString(Charset), 可以将字节数组输出流中的数据按照指定的编码转成字符串。可以更灵活的解决乱码问题。
String str = "蓝影铁哥";
ByteArrayInputStream bis = new ByteArrayInputStream(str.getBytes("GBK"));
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int b;
while ((b = bis.read()) != -1) {
bos.write(b);
}
//默认utf-8
System.out.println(bos.toString());// ��Ӱ����
System.out.println(bos.toString("GBK"));// 蓝影铁哥
在JDK10中给IO流中的很多类都添加了带Charset参数的方法,比如PrintStream、PrintWriter。通过Charset可以指定编码来操作文本。Charset是一个抽象类,我们不能直接创建对象,需要使用Charset的静态方法forName(“编码”),返回Charset的子类实例。
例如:PrintStream
// IO流很多类新增带Charset参数的构造方法
public static void main(String[] args) throws Exception {
String str = "蓝影铁哥";
var p = new PrintWriter("d:/fe.txt","utf-8");// 将字符串输出到d盘的fe.txt文件中
p.println(str);
p.flush();
p.close();
}
这个文本内容的编码就是代码中的utf-8编码,如果代码改成gbk,这文本内容编码也会变成gbk。
JDK10 给 InputStream 和 Reader 类中新增了 transferTo 方法, transferTo 方法的作用是将输入流读取的数据使用字符输出流写出。可用于复制文件等操作。
例如 Reader:
从这个Reader中读取所有字符串,并按照所读取的顺序将字符串写入给指定的Writer。
// InputStream和Reader新增了transferTo方法
public static void main(String[] args) throws Exception {
var reader = new BufferedReader(new InputStreamReader(new FileInputStream("d:/fe.txt")));
var p = new PrintWriter(new File("d:/feNew.txt"));
reader.transferTo(p);// 从这个Reader中读取所有字符串,并按照所读取的顺序将字符串写入给指定的Writer。
p.flush();
p.close();
reader.close();
}
在JDK10中给java.util.Formatter、java.util.Scanner添加了带Charset参数的构造方法。
例如:Scanner
// Formatter和Scanner新增了带Charset参数的构造方法
public static void main(String[] args) throws Exception {
var scanner = new Scanner(new FileInputStream(new File("d:/fe.txt")),"utf-8");// 之前写入的一行文字: 蓝影铁哥
while (scanner.hasNext()){
System.out.println(scanner.nextLine());// 蓝影铁哥
}
}