我有点想用JDK17了

大家好呀,我是summo,JDK版本升级的非常快,现在已经到JDK20了。JDK版本虽多,但应用最广泛的还得是JDK8,正所谓“他发任他发,我用Java8”。

其实我也不太想升级JDK版本,感觉投入高,收益小,不过有一次我看到了一些使用JDK17新语法写的代码,让我改变了对升级JDK的看法,因为这些新语法我确实想用!

废话不多说,上代码!

一、JDK17语法新特性

1. 文本块

这个更新非常实用。在没有这个特性之前,编写长文本非常痛苦。虽然IDEA等集成开发工具可以自动处理,但最终效果仍然丑陋,充满拼接符号。现在,通过字符串块,我们可以轻松编写JSON、HTML、SQL等内容,效果更清爽。这个新特性值得五颗星评价,因为它让我们只需关注字符串本身,而无需关心拼接操作。

原来的写法

/**
 * 使用JDK8返回HTML文本
 *
 * @return 返回HTML文本
 */
public static final String getHtmlJDK8() {
    return "<html>\n" +
        " <body>\n" +
        " <p>Hello, world</p>\n" +
        " </body>\n" +
        "</html>";
}

新的写法

/**
 * 使用JDK17返回HTML文本
 *
 * @return 返回HTML文本
 */
public static final String getHtmlJDK17() {
    return """
        <html>
            <body>
                <p>Hello, world</p>
            </body>
        </html>
        """;
}

推荐指数:⭐️⭐️⭐️⭐️⭐️

2. NullPointerException增强

这一功能非常强大且实用,相信每位Java开发者都期待已久。空指针异常(NPE)一直是Java程序员的痛点,因为报错信息无法直观地指出哪个对象为空,只抛出一个NullPointerException和一堆堆栈信息,定位问题耗时且麻烦。尤其在遇到喜欢级联调用的代码时,逐行排查更是令人头疼。如果在测试环境中,可能还需通过远程调试查明空对象,费时费力。为此,阿里的编码规范甚至不允许级联调用,但这并不能彻底解决问题。Java17终于在这方面取得了突破,提供了更详细的空指针异常信息,帮助开发者迅速定位问题源头。

public static void main(String[] args) {
    try {
        //简单的空指针
        String str = null;
        str.length();
    } catch (Exception e) {
        e.printStackTrace();
    }
    try {
        //复杂一点的空指针
        var arr = List.of(null);
        String str = (String)arr.get(0);
        str.length();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

运行结果

推荐指数:⭐️⭐️⭐️⭐️⭐️

3. Records

在Java中,POJO对象(如DO、PO、VO、DTO等)通常包含成员变量及相应的Getter和Setter方法。尽管可以通过工具或IDE生成这些代码,但修改和维护仍然麻烦。Lombok插件为此出现,能够在编译期间自动生成Getter、Setter、hashcode、equals和构造函数等代码,使用起来方便,但对团队有依赖要求。
为此,Java引入了标准解决方案:Records。它通过简洁的语法定义数据类,大大简化了POJO类的编写,如下所示。虽然hashcode和equals方法仍需手动编写,但IDE能够自动生成。这一特性有效解决了模板代码问题,提升了代码整洁度和可维护性。

package com.summo.jdk17;

/**
 * 3星
 *
 * @param stuId     学生ID
 * @param stuName   学生名称
 * @param stuAge    学生年龄
 * @param stuGender 学生性别
 * @param stuEmail  学生邮箱
 */
public record StudentRecord(Long stuId,
                            String stuName,
                            int stuAge,
                            String stuGender,
                            String stuEmail) {
    public StudentRecord {
        System.out.println("构造函数");
    }

    public static void main(String[] args) {
        StudentRecord record = new StudentRecord(1L, "张三", 16, "男", "xxx@qq.com");
        System.out.println(record);
    }
}

推荐指数:⭐️⭐️⭐️⭐️

4. 全新的switch表达式

有人可能问了,Java语言不早已支持switch了嘛,有什么好提的?讲真,这次的提升还真有必要好好地来聊一聊了。在Java12的时候就引入了switch表达式,注意这里是表达式,而不是语句,原来的switch是语句。如果不清楚两者的区别的话,最好先去了解一下。主要的差别就是就是表达式有返回值,而语句则没有。再配合模式匹配,以及yield和“->”符号的加入,全新的switch用起来爽到飞起来。

package com.summo.jdk17;

public class SwitchDemo {
    /**
     * 在JDK8中获取switch返回值方式
     *
     * @param week
     * @return
     */
    public int getByJDK8(Week week) {
        int i = 0;
        switch (week) {
            case MONDAY, TUESDAY:
                i = 1;
                break;
            case WEDNESDAY:
                i = 3;
                break;
            case THURSDAY:
                i = 4;
                break;
            case FRIDAY:
                i = 5;
                break;
            case SATURDAY:
                i = 6;
                break;
            case SUNDAY:
                i = 7;
                break;
            default:
                i = 0;
                break;
        }

        return i;
    }

    /**
     * 在JDK17中获取switch返回值
     *
     * @param week
     * @return
     */
    public int getByJDK17(Week week) {
        // 1, 现在的switch变成了表达式,可以返回值了,而且支持yield和->符号来返回值
        // 2, 再也不用担心漏写了break,而导致出问题了
        // 3, case后面支持写多个条件
        return switch (week) {
            case null -> -1;
            case MONDAY -> 1;
            case TUESDAY -> 2;
            case WEDNESDAY -> 3;
            case THURSDAY -> {yield 4;}
            case FRIDAY -> 5;
            case SATURDAY, SUNDAY -> 6;
            default -> 0;
        };
    }

    private enum Week {
        MONDAY,
        TUESDAY,
        WEDNESDAY,
        THURSDAY,
        FRIDAY,
        SATURDAY,
        SUNDAY
    }
}

推荐指数:⭐️⭐️⭐️⭐️

5. 私有接口方法

从Java8开始,允许在interface里面添加默认方法,其实当时就有些小困惑,如果一个default方法体很大怎么办,拆到另外的类去写吗?实在有些不太合理,所以在Java17里面,如果一个default方法体很大,那么可以通过新增接口私有方法来进行一个合理的拆分了,为这个小改进点个赞。

public interface PrivateInterfaceMethod {
    /**
     * 接口默认方法
     */
    default void defaultMethod() {
        privateMethod();
    }

    // 接口私有方法,在Java8里面是不被允许的,不信你试试
    private void privateMethod() {
    }
}

推荐指数:⭐️⭐️⭐️

6. 模式匹配

在JDK 17中,模式匹配主要用于instanceof表达式。模式匹配增强了instanceof的语法和功能,使类型检查和类型转换更加简洁和高效。在传统的Java版本中,我们通常使用instanceof结合类型转换来判断对象类型并进行处理,这往往会导致冗长的代码。

原来的写法

/**
 * 旧式写法
 *
 * @param value
 */
public void matchByJDK8(Object value) {
    if (value instanceof String) {
        String v = (String)value;
        System.out.println("遇到一个String类型" + v.toUpperCase());
    } else if (value instanceof Integer) {
        Integer v = (Integer)value;
    System.out.println("遇到一个整型类型" + v.longValue());
    }
}

新的写法

/**
 * 转换并申请了一个新的变量,极大地方便了代码的编写
 *
 * @param value
 */
public void matchByJDK17(Object value) {
    if (value instanceof String v) {
        System.out.println("遇到一个String类型" + v.toUpperCase());
    } else if (value instanceof Integer v) {
        System.out.println("遇到一个整型类型" + v.longValue());
    }
}

推荐指数:⭐️⭐️⭐️⭐️

7. 集合类的工厂方法

在Java8的年代,即便创建一个很小的集合,或者固定元素的集合都是比较麻烦的,为了简洁一些,有时我甚至会引入一些依赖。

原来的写法

Set<String> set = new HashSet<>();
set.add("a");
set.add("b");
set.add("c"

新的写法

Set<String> set = Set.of("a", "b", "c");

推荐指数:⭐️⭐️⭐️⭐️⭐️

二、其他的新特性

1. 新的String方法

  • repeat:重复生成字符串
  • isBlank:不用在引入第三方库就可以实现字符串判空了
  • strip:去除字符串两边的空格,支持全角和半角,之前的trim只支持半角
  • lines:能根据一段字符串中的终止符提取出行为单位的流
  • indent:给字符串做缩进,接受一个int型的输入
  • transform:接受一个转换函数,实现字符串的转换

2. Stream API的增强

增加takeWhile, dropWhile, ofNullable, iterate以及toList的API,越来越像一些函数式语言了。用法举例如下。

// takeWhile 顺序返回符合条件的值,直到条件不符合时即终止继续判断,
// 此外toList方法的加入,也大大减少了节省了代码量,免去了调用collect(Collectors::toList)方法了
List<Integer> list = Stream.of(2,2,3,4,5,6,7,8,9,10)
        .takeWhile(i->(i%2==0)).toList(); // 返回2, 2

// dropWhile 顺序去掉符合条件的值,直到条件不符合时即终止继续判断
List<Integer> list1 = Stream.of(2,2,3,4,5,6,7,8,9,10)
        .dropWhile(i->(i%2==0)).toList(); //返回3, 4, 5, 6, 7, 8, 9, 10

// ofNullable,支持传入空流,若没有这个且传入一个空流,那么将会抛NPE
var nullStreamCount = Stream.ofNullable(null).count(); //返回0

// 以下两行都将输出0到9
Stream.iterate(0, n -> n < 10, n -> n + 1).forEach(x -> System.out.println(x));
Stream.iterate(0, n -> n + 1).limit(10).forEach(x -> System.out.println(x));

3. 全新的HttpClient

这个API首次出现在9之中,不过当时并非是一个稳定版本,在Java11中正式得到发布,所以在Java17里面可以放心地进行使用。原来的JDK自带的Http客户端真的非常难用,这也就给了很多像okhttp、restTemplate、Apache的HttpClient和feign这样的第三方库极大的发挥空间,几乎就没有人愿意去用原生的Http客户端的。但现在不一样了,感觉像是新时代的API了。FluentAPI风格,处处充满了现代风格,用起来也非常地方便,再也不用去依赖第三方的包了,就两个字,清爽。

// 同步请求
HttpClient client = HttpClient.newBuilder()
        .version(Version.HTTP_1_1)
        .followRedirects(Redirect.NORMAL)
        .connectTimeout(Duration.ofSeconds(20))
        .proxy(ProxySelector.of(new InetSocketAddress("proxy.example.com", 80)))
        .authenticator(Authenticator.getDefault())
        .build();
   HttpResponse<String> response = client.send(request, BodyHandlers.ofString());
   System.out.println(response.statusCode());
   System.out.println(response.body()); 
// 异步请求
HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create("https://foo.com/"))
        .timeout(Duration.ofMinutes(2))
        .header("Content-Type", "application/json")
        .POST(BodyPublishers.ofFile(Paths.get("file.json")))
        .build();
   client.sendAsync(request, BodyHandlers.ofString())
        .thenApply(HttpResponse::body)
        .thenAccept(System.out::println);
 

4. jshell

在新的JDK版本中,支持直接在命令行下执行java程序,类似于python的交互式REPL。简而言之,使用 JShell,你可以输入代码片段并马上看到运行结果,然后就可以根据需要作出调整,这样在验证一些简单的代码的时候,就可以通过jshell得到快速地验证,非常方便。

5. java命令直接执行java文件

在现在可以直接通过执行“java xxx.java”,即可运行该java文件,无须先执行javac,然后再执行java,是不是又简单了一步。

6. ZGC

在ParallelOldGC、CMS和G1之后,JDK 11引入了全新的ZGC(Z Garbage Collector)。这个名字本身就显得很牛。官方宣称ZGC的垃圾回收停顿时间不超过10ms,能支持高达16TB的堆空间,并且停顿时间不会随着堆的增大而增加。那么,ZGC到底解决了什么问题?Oracle官方介绍它是一个可伸缩的低延迟垃圾回收器,旨在降低停顿时间,尽管这可能会导致吞吐量的降低。不过,通过横向扩展服务器可以解决吞吐量问题。官方已建议ZGC可用于生产环境,这无疑将成为未来的主流垃圾回收器。要了解更多,请参阅官方文档。

三、小结一下

作为程序员,持续学习和充电非常重要。随着Java8即将停止免费官方支持,越来越多的项目将转向Java17,包括大名鼎鼎的Spring Boot 3.0,它在2022年1月20日发布的第一个里程碑版本(M1)正是基于Java17构建的。该项目依赖的所有组件也将快速升级,未来如果想利用某些新特性,在Java8下将无法通过编译.,到这时候再换就真的晚了… …

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/678978.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【YOLO系列】YOLOv10论文超详细解读(翻译 +学习笔记)

前言 研究AI的同学们面对的一个普遍痛点是&#xff0c;刚开始深入研究一项新技术&#xff0c;没等明白透彻&#xff0c;就又迎来了新的更新版本——就像我还在忙着逐行分析2月份发布的YOLOv9代码&#xff0c;5月底清华的大佬们就推出了全新的v10。。。 在繁忙之余&#xff0…

Apple HEVC Stereo Video

1. 前言 为左眼和右眼携带立体视频视图的能力产生了更丰富的用户体验。 立体视频&#xff08;有时称为“3D 视频”&#xff09;向用户的左眼呈现一个图像&#xff0c;向用户的右眼呈现另一幅图像&#xff08;通常是相关的&#xff09;以产生立体效果&#xff0c;定义为&#x…

【经验】Ubuntu上离线安装VsCode插件浏览Linux kernel源码

1、下载VsCode离线安装包 1.1 下载 下载地址:https://marketplace.visualstudio.com/vscode 本人安装的插件: C/C++ checkpatch Chinese clangd kconfig Makefile Tools Perl Perl Toolbox注意:C/C++插件要安装Linux 64版本 1.2 安装 将离线安装包拷贝到Ubuntu中,执…

10 -力扣高频 SQL 50 题(基础版)

10 - 每台机器的进程平均运行时间 -- sum(if(activity_type end,timestamp ,-timestamp )) -- 如果activity_type为“end”,值为timestamp&#xff0c;为“start” 为-timestamp&#xff0c;所有数相加end-start -- count(distinct process_id),获取同一机器有几个进行id -- r…

C++系列-STL简介

&#x1f308;个人主页&#xff1a;羽晨同学 &#x1f4ab;个人格言:“成为自己未来的主人~” 什么是STL STL是C标准库的重要组成部分&#xff0c;不仅是一个可复用的组件库&#xff0c;而且是一个包罗数据结构与算法的软件框架。 STL的版本 原始版本 Alexander Stepa…

QT中将资源文件(image、qss、qm等)封装到静态库中,程序该如何引用静态库中的资源文件

1、静态库 2、主程序中使用第三方库中的资源文件 核心代码: int main(int argc, char *argv[]) {QApplication a(argc, argv

C++数组实现推箱子游戏

前言 我是三天打鱼两天晒网的闲人,今天跟着课程视频学习c的数组的运用. 准备好游戏用到的图片资源 代码逻辑实现 #include<iostream> #include<graphics.h> #include<string> #include<conio.h>using namespace std;//设置画布大小 #define SCREEN…

【SpringCloud学习笔记】Elasticsearch

1. Elasticsearch 1.1 安装ES 启动Docker&#xff1a;service docker restart / systemctl restart docker基于Docker创建网络docker network create hm-net向云服务器上传elasticsearch以及kibana的tar包&#xff0c;并使用docker load -i xxx.tar进行加载使用如下命令启动e…

使用Qt实现文本文件的读写操作

文章目录 文本读写简介QFileDialog简介常用方法示例代码 QFile简介常用方法示例代码 QTextStream简介常用方法示例代码 结合使用示例完整示例代码(读写操作&#xff0c;可直接复制运行我使用的Qt版本为QT5.14)mainwindow.hmainwindow.cppmain.cpp代码解释 文本读写简介 在现代…

k8s Pods漂移时间配置

默认为300秒 apiVersion: apps/v1 kind: Deployment metadata:name: my-test spec:replicas: 1selector:matchLabels:app: my-apptemplate:metadata:labels:app: my-appspec:containers:- name: my-containerimage: nginx:latestports:- containerPort: 80tolerations:- key: &…

MySQL之查询性能优化(四)

查询性能优化 MySQL客户端/服务器通信协议 一般来说&#xff0c;不需要去理解MySQL通信协议的内部实现细节&#xff0c;只需要大致理解通信协议是如何工作的。MySQL客户端和服务器之间的通信协议是"半双工"的&#xff0c;这意味着&#xff0c;在任何一个时刻&#…

History 模式和 Hash 模式路由的区别、优缺点及在开发生产环境中的注意事项

在现代单页应用&#xff08;SPA&#xff09;开发中&#xff0c;前端路由是至关重要的一部分。常见的路由模式有两种&#xff1a;History 模式和 Hash 模式。本文将详细探讨这两种模式的区别、优缺点&#xff0c;并在开发和生产环境中的注意事项。 路由模式简介 Hash 模式 H…

.Net 基于.Net8开发的一个Asp.Net Core Webapi后端框架

1.项目结构 该项目是基于.net8开发的Asp.Net Core WebApi后端服务,集成了Efcore,Autofac,Jwt,AutoMapper,Serilog,Quartz,MiniExcel等组件。该框架简单易上手&#xff0c;没有额外的学习成本; 该项目采用了多层结构设计&#xff0c;有利于解耦&#xff0c;包含公共层&#xff0…

机器视觉——硬件常用基础知识

光源 机器视觉中光源的作用 1&#xff09;强化特征&#xff0c;弱化背景 2&#xff09;光源打得好&#xff0c;图好了&#xff0c;后期算法更简化 3&#xff09;图好了&#xff0c;测试速度更高 各种光源的综合性能对比及为啥使用LED灯 光的颜色的选择 白色光&#xff1a;通常用…

【分享】两种方法禁止修改Word文档

对于比较重要的Word文件&#xff0c;不想被随意编辑修改&#xff0c;可以试试以下两个方法&#xff0c;不清楚的小伙伴&#xff0c;一起来看看吧&#xff01; 方法1&#xff1a;设置“只读方式” 我们可以给Word文档设置以“只读方式”打开&#xff0c;这样就算编辑修改了文档…

企业内部聊天软件Riot部署

ubuntu docker 简介 Riot(原Vector)是使用Matrix React SDK构建的Matrix网络聊天客户端,开源免费,功能丰富,支持私人对话,团队对话,语言视频对话,上传文件,社区互动。支持在聊天界面添加各种有趣的插件,比如RSS等各种机器人、虚拟币实时监控等。并且所有通过Riot传…

63. UE5 RPG 兼容没有武器的普通攻击

前面&#xff0c;我们实现了近战攻击技能&#xff0c;敌人通过AI靠近玩家&#xff0c;并且通过AI还能够触发近战攻击的释放。现在我们思考一个问题&#xff0c;如果敌人没有武器&#xff0c;攻击的手段是用的双手&#xff0c;我们该如何去获取它的攻击范围。 现在实现的一套是获…

什么情况!伯克希尔哈撒韦股票跌近100%

KlipC报道&#xff1a;当地时间6月3日开盘后&#xff0c;纽约证劵交易所的一个技术问题导致沃伦巴菲特(Warren Buffett)旗下伯克希尔哈撒韦公司(Berkshire Hathaway)A类股票似乎下跌了近100%&#xff0c;达到185.1美元/股。目前&#xff0c;所有受影响的股票已经恢复交易。 除了…

OLED_讲解

OLED&#xff08;有机发光二极管 Organic Light-Emitting Diode&#xff09;是一种显示技术&#xff0c;它使用有机化合物材料作为发光层&#xff0c;当通过电流时&#xff0c;这些材料会发光。OLED显示器由多个单独可控制的OLED像素组成&#xff0c;每个像素都能够发出红、绿、…

【异常分析:四分位距与3σ原则】

文章目录 前言四分位距&#xff08;IQR&#xff09;3σ原则使用步骤计算四分位距应用3σ原则 代码 前言 异常分析的目标是识别数据中的异常值&#xff0c;这些异常值可能是由于错误的记录、设备故障或者其他未知原因导致的。四分位距&#xff08;interquartile range, IQR&…