Z次元
文章 笔记 日志
专题
专栏分类
文章归档
友链
友情链接
朋友圈
留言
头像
系列文章
JDK新版特性(9-11)
2025/1/30
JDK新版特性(18-21)
2025/2/7
JDK新版特性(12-17)
2025/1/30
JDK新版特性(22-25)
2025/11/9
JDK新版特性(12-17)
系列文章
知识积累
更新于:2025/11/9
|
发布于:2025/1/30
文章摘要
......

JDK12

升级的switch语句

在jdk12之前的switch语句中,如果没有写break,则会出现case穿透现象,下面是对case穿透的一个应用,根据输入的月份打印相应的季节。

int month = 3;
switch (month) {
    case 3:
    case 4:
    case 5:
        System.out.println("spring");
    break;
    case 6:
    case 7:
    case 8:
        System.out.println("summer");
    break;
    case 9:
    case 10:
    case 11:
        System.out.println("autumn");
    break;
    case 12:
    case 1:
    case 2:
        System.out.println("winter");
    break;
    default:
        System.out.println("wrong");
    break;
}

在jdk12之后我们可以省略全部的break和部分case,这样使用

    int month = 3;
    switch (month) {
        case 3,4,5 -> System.out.println("spring");
        case 6,7,8 -> System.out.println("summer");
        case 9,10,11 -> System.out.println("autumn");
        case 12, 1,2 -> System.out.println("winter");
        default -> System.out.println("wrong");
    }

这个是预览功能,如果需要编译和运行的话需要使用下面命令,预览功能在2个版本之后会成为正式版,即如果你使用的是jdk14以上的版本,正常的编译和运行即可。否则需要使用预览功能来编译和运行

编译:
    javac --enable-preview -source 12 Test.java

运行:
    java --enable-preview Test

JDK13

升级的switch语句

jdk13中对switch语句又进行了升级,可以switch的获取返回值

示例:

   int month = 3;
   String result = switch (month) {
        case 3,4,5 -> "spring";
        case 6,7,8 -> "summer";
        case 9,10,11 -> "autumn";
        case 12, 1,2 -> "winter";
        default -> "wrong";
    };

    System.out.println(result);

对于jdk15之后的版本可以直接编译和运行,否则需要使用下面命令执行该预览功能

编译:
    javac --enable-preview -source 13 Test.java

运行:
    java --enable-preview Test

文本块的变化

在jdk13之前的版本中如果输入的字符串中有换行的话,需要添加换行符

String s = "Hello\nWorld\nLearn\nJava";
System.out.println(s);

jdk13之后可以直接这样写:

String s = """
            Hello
            World
            Learn
            Java
           """;
System.out.println(s);

这样的字符串更加一目了然。

JDK14

instanceof模式匹配

该特性可以减少强制类型转换的操作,简化了代码,代码示例:

public class TestInstanceof{
    public static void main(String[] args){

        //jdk14之前的写法
        Object obj = new Integer(1);
        if(obj instanceof Integer){
            Integer i = (Integer)obj;
            int result = i + 10;
            System.out.println(i);
        }

        //jdk14新特性  不用再强制转换了
        //这里相当于是将obj强制为Integer之后赋值给i了
        if(obj instanceof Integer i){
            int result = i + 10;
            System.out.println(i);
        }else{
            //作用域问题,这里是无法访问i的
        }
    }
}

这个是预览版的功能所以需要使用下面命令编译和运行

编译:
    javac --enable-preview -source 14 TestInstanceof.java

运行:
    java --enable-preview TestInstanceof

友好的空指针(NullPointerException)提示

jdk14中添加了对于空指针异常友好的提示,便于开发者快速定位空指针的对象。示例代码:

class Machine{
    public void start(){
        System.out.println("启动");
    }
}

class Engine{
    public Machine machine;
}

class Car{
    public Engine engine;

}

public class TestNull{
    public static void main(String[] args){
        //这里会报出空指针,但是哪个对象是null呢?
        new Car().engine.machine.start();
    }
}

我们在运行上面代码的时候,错误信息就可以明确的指出那个对象为null了。此外,还可以使用下面参数来查看:

java -XX:+ShowCodeDetailsInExceptionMessages TestNull

这样编译器会明确的告诉开发者哪个对象是null。

record类型

之前在编写javabean类的时候,需要编写成员变量,get方法,构造方法,toString方法,hashcode方法,equals方法。这些方法通常会通过开发工具来生成,在jdk14中新增了record类型,通过该类型可以省去这些代码的编写。

jdk14编写User

public record User(String name,Integer age){}

通过反编译命令可以看到该字节码文件中的内容,User类是继承了Record类型:

javap -p -private user

编写测试类:

public class TestUser{
    public static void main(String[] args){
        User u = new User("ahzoo",18);
        System.out.println(u);
        System.out.println(u.name());
    }
}

这个是预览版的功能所以需要使用下面命令编译和运行

编译:
    javac --enable-preview -source 14 TestUser.java

运行:
    java --enable-preview TestUser

记录类型有自动生成的成员,包括:

  • 状态描述中的每个组件都有对应的private final字段。

  • 状态描述中的每个组件都有对应的public访问方法。方法的名称与组件名称相同。

  • 一个包含全部组件的公开构造器,用来初始化对应组件。

  • 实现了equals()和hashCode()方法。equals()要求全部组件都必须相等。

  • 实现了toString(),输出全部组件的信息。

JDK15

Sealed Classes

密封类和接口,作用是限制一个类可以由哪些子类继承或者实现。

  1. 如果指定模块的话,sealed class和其子类必须在同一个模块下。如果没有指定模块,则需要在同一个包下。

  2. sealed class指定的子类必须直接继承该sealed class。

  3. sealed class的子类要用final修饰。

  4. sealed class的子类如果不想用final修饰的话,可以将子类声明为sealed class。

Animal类,在指定允许继承的子类时可以使用全限定名

public sealed class Animal 
    permits Cat, Dog{//多个子类之间用,隔开

        public void eat(){}
}

Cat类

public final class Cat extends Animal{
    public void eat(){
        System.out.println("123");
    }
}

Dog类

public sealed class Dog extends Animal permits Husky {}

Husky类

public final class Husky extends Dog{
}

Test类

public class Test{
    public static void main(String[] args){
        Cat c = new Cat();
        c.eat();
        Dog d = new Dog();
    }
}

CharSequence新增的方法

该接口中新增了default方法isEmpty(),作用是判断CharSequence是否为空。

TreeMap新增方法

putIfAbsent、 computeIfAbsent 、computeIfPresent 、compute 、merge

文本块

文本块由预览版变为正式版

JDK16

包装类构造方法的警告

​ 使用包装类的构造方法在编译的时候会出现警告,不建议再使用包装类的构造方法。下面代码在javac编译之后会出现警告。

Integer i = new Integer(8);

不建议使用包装类作为锁对象,倘若使用包装类作为锁对象,在编译时会出现警告。

Integer i = 8;
synchronized(i){
}

新增日时段

在DateTimeFormatter.ofPattern传入B可以获取现在时间对应的日时段,上午,下午等

System.out.println(DateTimeFormatter.ofPattern("B").format(LocalDateTime.now()));

InvocationHandler新增方法

在该接口中添加了下面方法

public static Object invokeDefault(Object proxy, Method method, Object... args)

该方法可以调用父接口中defalut方法,比如有下面接口

interface Girl{
    default void eat(){
        System.out.println("cucumber");
    }

}

实现类

public class Lucy implements Girl{
    public void eat(){
        System.out.println("banana");
    }
}

测试类:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class Test{
    public static void main(String[] args) {
        Girl girl = new Lucy();


        //不使用invokeDefault会调用重写的eat方法
        Girl proxy1 = (Girl)Proxy.newProxyInstance(girl.getClass().getClassLoader(),girl.getClass().getInterfaces(),
            (obj,method,params)->{
            Object invoke = method.invoke(girl);
            return invoke;
        });
        proxy1.eat();

        //使用invokeDefault会调用父接口中的default方法
        Girl proxy2 = (Girl)Proxy.newProxyInstance(Girl.class.getClassLoader(),new Class<?>[]{Girl.class},
            (obj,method,params)->{
            if (method.isDefault()) {
                return InvocationHandler.invokeDefault(obj, method, params);
            }
            return null;
        });
        proxy2.eat();

    }

}

JDK17

java17是一个LTS(long term support)长期支持的版本。

switch语法的变化(预览)

Sealed Classes

在jdk15中已经添加了Sealed Classes,只不过当时是作为预览版,经历了2个版本之后,在jdk17中Sealed Classes已经成为正式版了。Sealed Classes的作用是可以限制一个类或者接口可以由哪些子类继承或者实现。

参考文章:https://zhuanlan.zhihu.com/p/390679021

版权声明
本文依据 CC-BY-NC-SA 4.0 许可协议授权,请您在转载时注明文章来源为 Z次元 ,若本文涉及转载第三方内容,请您一同注明。
更多专栏文章推荐
知识积累
人非生而知之者,孰能无惑?惑而不从师,其为惑也,终不解矣。
JDK新版特性(9-11)
2025/1/30
将Maven项目组件上传到Maven中心仓(借助sonatype)
2024/6/8
JDK8升级JDK21报错解决方案记录
2025/12/28
MySQL模糊查询的多种方式
2025/12/4
评论区

删除确认

评论删除后无法恢复,请确认是否继续?
发表评论

这里还没有评论哦

快来发一条评论抢占前排吧

目录
1
JDK12
升级的switch语句
2
JDK13
升级的switch语句
文本块的变化
3
JDK14
instanceof模式匹配
友好的空指针(NullPointerException)提示
record类型
4
JDK15
Sealed Classes
CharSequence新增的方法
TreeMap新增方法
文本块
5
JDK16
包装类构造方法的警告
新增日时段
InvocationHandler新增方法
6
JDK17
switch语法的变化(预览)
Sealed Classes
目录
1
JDK12
升级的switch语句
2
JDK13
升级的switch语句
文本块的变化
3
JDK14
instanceof模式匹配
友好的空指针(NullPointerException)提示
record类型
4
JDK15
Sealed Classes
CharSequence新增的方法
TreeMap新增方法
文本块
5
JDK16
包装类构造方法的警告
新增日时段
InvocationHandler新增方法
6
JDK17
switch语法的变化(预览)
Sealed Classes
博客
文章 笔记 日志
专题
专栏分类 文章归档
友链
友情链接 朋友圈
交流
留言 关于我
主页
菜单
置顶
主题
我的
十玖八柒
每天进步多一点
欢迎到访φ(゜▽゜*)♪
最新评论
柒: @Honesty
因为这个系列主要是总结和代码相关的特性,不过这个特性感觉确实可以写一下
Honesty:
哎?Jdk25 对象头压缩这个很重要的特性没记呢
个人占星:
DeepSeek没有想象中的好用
个人占星:
想给自己的网站弄个统计功能,但不会弄,头疼
我的
关于我
个人主页
站点地图
RSS订阅
导航
十年之约
虫洞穿梭
开源博客
前端开源仓库
后端开源仓库
©2020 - 2026 By 十玖八柒 版权所有
豫ICP备20021466号