目录
JDK5
基本数据类型自动装箱拆箱
可变参数
增强for
注解
泛型
枚举
概述
定义
常用方法
自定义构造方法
枚举类中的抽象方法
JDK7
二进制字面量
switch
异常
try-with-resources,自动关流
JDK11
FileInputStream增强
String类增强
Stream流增强
List增强
全新的垃圾回收器ZGC
ZGC的优势
可变类型var
概述
注意点
JDK17
增强型伪随机数发生器
RandomGeneratorFactory
RandomGenerator
强封装JDK的内部API
switch增强
密封类
全面提速
JDK5
jdk5是java的标志性版本,提供了众多影响深远的功能,是java质变的版本
基本数据类型自动装箱拆箱
基本数据类型和其包装类的转换,运算,不再需要显式的使用构造方法,intValue()等方式,直接就可以互相运算,赋值
Integer a = 1;
int b = a;
int c = a + b;
可变参数
方法的参数可以不是固定个数,编译器会隐式的使用一个数组去接收参数
注意
可变参数显然只能放在所有参数的最后,因为它会把所有的参数都接收
public static Integer getSum(int ... nums){int sum = 0 ;for(int num : nums){sum += num;}return sum;
}
增强for
对于数组,集合,不再需要通过角标,迭代器去遍历,极大的简化了操作
for (Integer num : numArr/numList) {System.out.println(num);
}
注解
遍地开花的注解功能也是在jdk5引入
泛型
菱形泛型也是在jdk5引入
枚举
概述
将一类变量的值罗列出来,变量的值只限于列举出来的值的范围内
举例:一周7天,一年12个月
定义
public enum GenderEnum {GENDER_0,GENDER_1;
}
常用方法
E.values(); 获取枚举值数组,values()是编译器提供的方法,并不是枚举类本身携带的方法,这并不妨碍我们使用
E.valueOf("MONDAY"); 获取指定枚举值
自定义构造方法
简单的枚举类显然没办法满足我们的业务需求,因为我们不大可能把这些字段都定义为枚举类型,因此需要通过自定义构造丰富枚举的使用
public enum GenderEnum {GENDER_0("0", "女"),GENDER_1("1", "男");private String key;private String val;//自定义构造private GenderEnum(String key, String val) {this.key = key;this.val = val;}//通过key获取valpublic static String toVal(String k) {GenderEnum [] ems = values();for (GenderEnum e : ems) {if(e.k().equals(k)) {return e.v();}}return null;}//通过val获取keypublic static String toKey(String v) {GenderEnum [] ems = values();for (GenderEnum e : ems) {if(e.v().equals(v)) {return e.k();}}return null;}public static Integer toIntKey(String v) {GenderEnum [] ems = values();for (GenderEnum e : ems) {if(e.v().equals(v)) {return Integer.parseInt(e.k());}}return null;}public static Map<String,String> toMap() {return Arrays.stream(values()).collect(Collectors.toMap(GenderEnum::k, GenderEnum::v));}//获取keypublic String k() {return key;}//获取valpublic String v() {return val;}
}
枚举类中的抽象方法
枚举类中可以定义抽象方法,那么每个枚举值都要重写该方法,通常不会特别的使用
枚举还提供了专用的EnumMap,EnumSet,但通常也不会特别使用它们
public enum GenderEnum {GENDER_1("1", "男") {@Overridepublic String getString() {return "男-字符串";}};//抽象方法public abstract String getString();private String key;private String val;private RoleEnum(String key, String val) {this.key = key;this.val = val;}
JDK7
jdk8之前最重要的过渡版本
二进制字面量
在二进制数前面加上0b,0B标记这是一个二进制数
System.out.println(0b110);
switch
case语句可以用String类型进行匹配,是的没错,jdk7以前case表达式不可以用String类型
String month = "1";
switch (month) {case "1":return "一月";case "2":return "二月";default:return null;
}
异常
多个catch可以合并到一个处理体,异常用 | 符号间隔
try {...
} catch (NoSuchFieldException | IllegalAccessException e) {...
} finally {...
}
try-with-resources,自动关流
使用该方式,不再需要手动close()关流
//不需要手动关流,代码块执行完会自动关流,可以声明多个流
try(InputStream inputStream = file.getInputStream();InputStream inputStream2 = file2.getInputStream()) {...inputStream1...inputStream2...
}//如果手动关流
try {InputStream inputStream = file.getInputStream()...
} catch(Exception e) {...
} finally {...if(inputStream != null) {inputStream .close();}
}
JDK11
jdk8之后第二个LTS版本,提供了新的垃圾回收期ZGC
FileInputStream增强
FileInputStream可以直接写入FileOutputStream
fis.transferTo(fos);
String类增强
str.isBlank(); //trim后是否为空
str.lines(); //按照终止符分割为stream流
str.repeat(num); //复制num次,组成新的字符串
str.strip();
str.stripLeading();
str.stripTrailing();
Stream流增强
截止结算
takeWhile(),从集合中取出满足条件的元素,直到不满足条件
dropWhile(),从集合中移除满足条件的元素,直到不满足条件
从单个数据构造流
Stream.ofNullable(null);
Optional.of("foo").stream(); Optionals可以直接转为Stream
List增强
集合转数组
List<String> sampleList = Arrays.asList("张三", "java 11");
// array = {"张三", "java 11"};
String[] array = sampleList.toArray(String[]::new);
全新的垃圾回收器ZGC
ZGC的优势
GC暂停时间不会超过10毫秒
既能处理几百兆的小堆,也能处理几个T的大堆
和G1相比,应用吞吐能力不会下降超过15%
为未来的GC功能和利用colord指针以及Load barriers优化奠定了基础
ZGC是一个并发、基于region、压缩型的垃圾收集器,只有root扫描阶段会STW(strop the world,停止所有线程),因此ZGC的停顿时间不会随着堆的增长和存活对象的增长而变长
用法:-XX:UnlockExperimentalVMOptions -XX:+UseZGC2
可变类型var
概述
允许使用var作为变量定义时的类型声明
var x = 10;
注意点
要在定义时进行初始化
var x;
x = "var"; //编译时提示无法推断类型
类型无法互相兼容
var x = 10;
x = "var"; //提示类型不兼容
成员变量无法使用
增强for中可以使用var
for(var str : list) {...}
JDK17
springboot3不再兼容低版本的JDK,要求至少为JDK17
这意味着兼容springboot3的其他开源项目也开始要求更高版本的JDK,升级JDK17很有必要
此外,JDK17相比较JDK8,JDK11在性能上明显更好,值得升级
增强型伪随机数发生器
RandomGeneratorFactory
public static Stream> all() 获取可选的随机数算法列表
public static RandomGeneratorFactory of(String name) 获取给定随机数算法的RandomGeneratorFactory
public T create(long seed) 获取给定种子的RandomGenerator
RandomGenerator
default int nextInt(int bound) 获取一个bound范围内的同类型随机数
RandomGeneratorFactory.all().forEach(e->{System.out.println(e.name());
});
//输出
L32X64MixRandom
L128X128MixRandom
L64X128MixRandom
SecureRandom
L128X1024MixRandom
L64X128StarStarRandom
Xoshiro256PlusPlus
L64X256MixRandom
Random
Xoroshiro128PlusPlus
L128X256MixRandom
SplittableRandom
L64X1024MixRandomRandomGeneratorFactory<RandomGenerator> l128X128MixRandom = RandomGeneratorFactory.of("L128X128MixRandom");
RandomGenerator randomGenerator = l128X128MixRandom.create(System.currentTimeMillis());
System.out.println(randomGenerator.nextInt(100));
强封装JDK的内部API
对JDK提供的类进行广泛的强封装,默认情况下,开发者不再能通过反射访问非公有成员
switch增强
实际上,JDK8~JDK17之间的版本已经对switch进行了多次增强
从JDK14开始,switch支持lambda编写case语句体,而且可以带返回值
Integer month = 1;
String monthStr = switch (month) {case 1-> "一月";default -> "未知";
};System.out.println(monthStr);
网上很多文档说JDK17给case匹配提供了模式匹配
但经过实际测试,这个功能已经被放到JDK19,当下的JDK17已经无法使用这个功能
Object month = 1d;
switch (month) {case Integer i -> System.out.println("这是Integer");case Double d -> System.out.println("这是Double");default -> System.out.println("未知");
}
密封类
Sealed关键字
一个类被Sealed修饰,将会只允许permits指定的类继承,实现类必须有final或者no-sealed修饰
为什么要用fianl修饰:为了密封类继承的安全性
public sealed class Person permits Student{private String name;
}public final class Student extends Person{}
全面提速
JDK17在代码执行,GC效率上相比JDK8,JDK11都有了明显提升