JDK5,7,11,17特性

目录

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获取val
   public static String toVal(String k) {
      GenderEnum [] ems = values();
      for (GenderEnum e : ems) {
         if(e.k().equals(k)) {
            return e.v();
         }
      }
      return null;
   }
   
   //通过val获取key
   public 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 toMap() {
      return Arrays.stream(values()).collect(Collectors.toMap(GenderEnum::k, GenderEnum::v));
   }
    //获取key
   public String k() {
      return key;
   }
    //获取val
   public String v() {
      return val;
   }
}

枚举类中的抽象方法

枚举类中可以定义抽象方法,那么每个枚举值都要重写该方法,通常不会特别的使用

枚举还提供了专用的EnumMap,EnumSet,但通常也不会特别使用它们

public enum GenderEnum {
   GENDER_1("1", "男") {
      @Override
      public 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 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
L64X1024MixRandom

RandomGeneratorFactory 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都有了明显提升

你可能感兴趣的:(jdk,javase)