JDK 8到JDK 17都有哪些吸引人的特性?

news2024/12/27 10:05:59

从JDK 8到JDK 17,Java语言和平台经历了许多变化和改进,引入了许多吸引人的新特性和功能。在这里,给大家列举一些我认为最有趣或最有用的新特性,并会以实际使用案例为大家展示新用法。希望大家多多点赞关注!!

1. JDK 8之Lambda表达式和Stream API

JDK 8带来了许多新的语言特性,其中最引人注目的是Lambda表达式和Stream API。Lambda表达式允许Java开发人员使用更简洁的语法编写函数式代码,这使得代码更易于阅读和维护。Stream API则为Java开发人员提供了一种便捷的方式来处理集合和数据流,使得代码更加简洁和易于理解。

大家可以看下我之前的文章里面对Lambda常用的做了详细介绍。

2. JDK 9之平台模块系统

JDK 9引入了Java平台模块系统,这是一个重大的变化。模块系统允许开发人员将代码组织成模块,并且可以控制模块之间的依赖关系。这使得代码更加模块化,并且可以更好地管理代码库和依赖项,以下是常见的举例:

  1. java.base: 这是Java平台的基本模块,提供了核心的API和功能,包括集合框架、并发工具、I/O操作等。它是其他模块的基础依赖。

  2. java.sql: 这个模块包含了Java数据库连接(JDBC)相关的API和实现,允许开发者与各种关系型数据库进行交互。

  3. java.xml: 这个模块提供了对XML文档的解析和处理功能,包括DOM、SAX等API,使得开发者可以方便地读取和操作XML数据。

  4. java.logging: 这个模块提供了Java的日志记录功能,允许开发者在应用程序中记录和管理日志信息。

  5. java.desktop: 这个模块提供了与桌面应用程序相关的功能,包括AWT(Abstract Window Toolkit)和Swing等用户界面组件。

  6. java.management: 这个模块提供了对Java虚拟机(JVM)管理和监控的API,允许开发者获取和操作JVM的运行时信息。

  7. java.net.http: 这个模块提供了一个简单易用的HTTP客户端API,使得开发者可以方便地发送HTTP请求和处理响应。
    在这里插入图片描述

3. JDK 10之局部变量类型推断

JDK 10引入了局部变量类型推断,这使得开发人员可以在不显式指定变量类型的情况下声明变量。这使得代码更加简洁,并且可以减少重复的代码。允许在声明局部变量时使用关键字 var 来自动推断变量的类型。这在某些情况下可以简化代码,并提高代码的可读性和编写效率。

以下是一些使用局部变量类型推断的实际例子:

基本类型推断:

var age = 25; // 推断为 int
var pi = 3.14159; // 推断为 double

对象类型推断:

var list = new ArrayList<String>(); // 推断为 ArrayList<String>
var map = new HashMap<Integer, String>(); // 推断为 HashMap<Integer, String>

循环迭代器类型推断:

var numbers = List.of(1, 2, 3, 4, 5);
for (var number : numbers) {
    System.out.println(number); // 推断为 Integer
}

Lambda 表达式类型推断:

var runnable = (Runnable) () -> {
    System.out.println("Hello, World!"); // 推断为 Runnable
};

try-with-resources 语句类型推断:

try (var reader = new BufferedReader(new FileReader("file.txt"))) {
    // 使用 reader 读取文件内容
} catch (IOException e) {
    // 处理异常
}

4. JDK 11之HTTP客户端API

JDK 11引入了HTTP客户端API,这是一个全新的HTTP客户端实现。这使得开发人员可以更加轻松地与网络进行交互,并且可以更加灵活地配置和管理HTTP请求。

发送GET请求并获取响应:

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class HttpClientExample {
    public static void main(String[] args) throws Exception {
        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("https://api.example.com/users"))
                .GET()
                .build();

        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
        System.out.println(response.body());
    }
}

发送POST请求并获取响应:

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.http.HttpHeaders;
import java.net.http.HttpResponse.BodyHandlers;
import java.nio.charset.StandardCharsets;
import java.util.Map;

public class HttpClientExample {
    public static void main(String[] args) throws Exception {
        HttpClient client = HttpClient.newHttpClient();

        // 构建请求体
        String requestBody = "username=testuser&password=pass123";
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("https://api.example.com/login"))
                .header("Content-Type", "application/x-www-form-urlencoded")
                .POST(HttpRequest.BodyPublishers.ofString(requestBody))
                .build();

        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
        System.out.println(response.statusCode());
        System.out.println(response.body());
    }
}

发送带有Headers和查询参数的请求:

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.http.HttpHeaders;

public class HttpClientExample {
    public static void main(String[] args) throws Exception {
        HttpClient client = HttpClient.newHttpClient();

        // 构建请求URL,包括查询参数
        URI uri = URI.create("https://api.example.com/search?query=java");
        
        // 添加Headers
        HttpRequest request = HttpRequest.newBuilder()
                .uri(uri)
                .header("Authorization", "Bearer XXXXXXXXXXXX")
                .GET()
                .build();

        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
        System.out.println(response.body());
    }
}

5. JDK 12之Switch表达式

JDK 12引入了Switch表达式,这是对传统Switch语句的扩展。Switch表达式允许开发人员以更简洁的方式编写Switch语句,并且可以更容易地处理多个值。

基本用法:

public class SwitchExample {
    public static void main(String[] args) {
        int dayOfWeek = 3;

        String dayType = switch (dayOfWeek) {
            case 1, 2, 3, 4, 5 -> "Weekday";
            case 6, 7 -> "Weekend";
            default -> throw new IllegalArgumentException("Invalid day of week: " + dayOfWeek);
        };
        
        System.out.println(dayType); // 输出:Weekday
    }
}

返回值和Lambda表达式:

public class SwitchExample {
    public static void main(String[] args) {
        String fruit = "apple";

        int count = switch (fruit) {
            case "apple" -> {
                System.out.println("Apple is selected.");
                yield 5; // 返回数量为 5
            }
            case "banana" -> {
                System.out.println("Banana is selected.");
                yield 3; // 返回数量为 3
            }
            default -> throw new IllegalArgumentException("Unknown fruit: " + fruit);
        };
        
        System.out.println("Number of fruits: " + count); // 输出:Number of fruits: 5
    }
}

空语句和复用标签:

public class SwitchExample {
    public static void main(String[] args) {
        String fruit = "orange";

        switch (fruit) {
            case "apple" -> System.out.println("Apple is selected.");
            case "banana" -> {
                System.out.println("Banana is selected.");
                break;
            }
            case "orange" -> {
                System.out.println("Orange is selected.");
                break;
            }
            default -> throw new IllegalArgumentException("Unknown fruit: " + fruit);
        }
        
        // 输出:Orange is selected.
    }
}

6. JDK 13之文本块

JDK 13引入了文本块,这是一种新的字符串语法。文本块允许开发人员以更简洁的方式编写多行字符串,这使得代码更加易于阅读和维护。

基本用法:

public class TextBlockExample {
    public static void main(String[] args) {
        String textBlock = """
            Hello, 
            this is a 
            text block.""";
        
        System.out.println(textBlock);
    }
}

结合变量插入:

public class TextBlockExample {
    public static void main(String[] args) {
        String name = "Alice";
        int age = 25;

        String textBlock = """
            Person Details:
            Name: %s
            Age: %d
            """.formatted(name, age);

        System.out.println(textBlock);
    }
}

保留缩进格式:

public class TextBlockExample {
    public static void main(String[] args) {
        String textBlock = """
            <html>
                <body>
                    <h1>Hello, World!</h1>
                </body>
            </html>
            """;

        System.out.println(textBlock);
    }
}

转义特殊字符:

public class TextBlockExample {
    public static void main(String[] args) {
        String textBlock = """
            This is a text block with special characters:
            - Tab: \t
            - Newline: \n
            - Backslash: \\
            """;

        System.out.println(textBlock);
    }
}
  1. JDK 14之Records

JDK 14引入了Records,这是一种新的Java类类型。记录允许开发人员以更简洁的方式定义数据对象,并提供了自动生成的方法,如equals和hashCode方法。

public record Person(String name, int age) {
    // 可以在这里添加其他字段、构造函数或方法

    public static void main(String[] args) {
        Person person = new Person("Alice", 25);
        
        System.out.println(person.name()); // 输出:Alice
        System.out.println(person.age());  // 输出:25
        
        // 编译器自动生成的toString()方法
        System.out.println(person);        // 输出:Person[name=Alice, age=25]
        
        Person otherPerson = new Person("Alice", 25);
        
        // 编译器自动生成的equals()方法
        System.out.println(person.equals(otherPerson)); // 输出:true
    }
}

在上面的示例中,Person是一个记录类,由关键字record来声明。它包含了两个字段name和age,并自动提供了相应的访问方法。此外,编译器还自动生成了equals()、hashCode()和toString()等方法,用于比较对象的相等性和生成字符串表示。

使用记录类可以更轻松地定义简单的数据封装类,避免手动编写大量的样板代码。记录类的字段默认是不可变的(final),在创建对象后无法修改其值。这使得记录类非常适合表示数据传输对象(DTO)或值对象(Value Object)。

8. JDK 15之Sealed Classes

JDK 15引入了Sealed Classes,这是一种新的类类型。封闭类允许开发人员限制类的继承,使得代码更加可靠和安全。

下面是使用JDK 15的Sealed Classes的一个示例:

public sealed class Shape permits Circle, Rectangle {
    // 可以在这里添加通用的方法或字段

    // 密封类中的方法可供子类选择性地重写
    public double area() {
        return 0;
    }
}

final class Circle extends Shape {
    private final double radius;

    public Circle(double radius) {
        this.radius = radius;
    }

    @Override
    public double area() {
        return Math.PI * radius * radius;
    }
}

final class Rectangle extends Shape {
    private final double length;
    private final double width;

    public Rectangle(double length, double width) {
        this.length = length;
        this.width = width;
    }

    @Override
    public double area() {
        return length * width;
    }
}

在上面的示例中,Shape是一个密封类,使用关键字sealed进行声明。Shape类使用permits关键字明确指定了允许继承的子类有Circle和Rectangle。这意味着除了这两个子类,其他类无法直接继承自Shape。

Circle和Rectangle是Shape的两个子类,它们分别表示圆和矩形。子类必须为密封类声明的方法提供实现。在示例中,Circle通过重写area()方法来计算圆的面积,Rectangle则通过重写area()方法来计算矩形的面积。

使用密封类可以限制继承的范围,提供更严格的类型检查和更安全的代码。在某些情况下,密封类还可以增加可读性和可维护性,使代码结构更清晰。

9. JDK 16之Pattern Matching for instanceof

JDK 16引入了Pattern Matching for instanceof(instanceof的模式匹配)的特性,它简化了对对象类型的判断和转换的代码。通过使用instanceof关键字和模式匹配,可以更方便地进行类型检查和类型转换,减少样板代码的编写。

下面是使用JDK 16的Pattern Matching for instanceof的一个示例:

public class Example {
    public static void main(String[] args) {
        Object obj = "Hello";

        if (obj instanceof String str) {
            System.out.println(str.length());  // 输出:5
            
            // 通过模式变量直接访问匹配后的对象
            System.out.println(str.toUpperCase());  // 输出:HELLO
        } else {
            System.out.println("Object is not a String");
        }
    }
}

在上面的示例中,我们有一个Object类型的对象obj,我们想要判断它是否是一个String类型的实例。在使用instanceof进行类型检查时,我们在判断条件的同时,通过使用as关键字创建了一个模式变量str,并将匹配成功的对象赋值给它。

如果obj是一个String类型的实例,那么就会执行if语句块内的代码。在这里,我们可以直接使用模式变量str来调用String类的方法,例如length()toUpperCase()

如果obj不是一个String类型的实例,那么就会执行else语句块内的代码。

使用Pattern Matching for instanceof可以更清晰地表达类型判断和转换的逻辑,减少了临时变量的使用,并使代码更加简洁。它提供了更高效、更安全的方式来处理对象类型的判断和转换。

10. JDK 17之弱引用垃圾回收器

JDK 17引入了许多新的功能和改进,其中包括弱引用垃圾回收器,ZGC的大型页支持和预测性空闲列表分配,以及JVM日志记录API的改进。
在这里插入图片描述

总的来说,JDK 8到JDK 17带来了许多令人兴奋的新特性和功能。这些新特性和功能使得Java开发更加容易、高效和有趣,同时也使得Java语言和平台更加强大和灵活。

今天将JDK 8到JDK 17的一些比较重大的改进和新特性就给大家分享到这里,希望大家多多点赞关注!后续会给大家持续分享技术知识,让我们一起进步!!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C语言的switch case函数

文章目录 1 函数结构2 执行过程3 break关键字4 补充说明参考 1 函数结构 switch 是另外一种选择结构的语句&#xff0c;用来代替简单的、拥有多个分枝的 if else 语句&#xff0c;基本格式如下&#xff1a; switch(表达式){ case 整型数值1: 语句 1; case 整型数值2: 语句 2; …

极致呈现系列之:Echarts词云图的数据共振

目录 什么是词云图词云图的特性及应用场景词云图的特性词云图的应用场景 Echarts中词云图的常用属性vue3中创建词云图 什么是词云图 词云图&#xff08;Word Cloud&#xff09;是一种以文字的形式展示数据的可视化图表。它通过将各个文字按照一定的规则排列&#xff0c;并根据…

车载软件架构 —— 闲聊几句AUTOSAR OS(六)

我是穿拖鞋的汉子,魔都中坚持长期主义的工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 没有人关注你。也无需有人关注你。你必须承认自己的价值,你不能站在他人的角度来反对自己。人生在世,最怕的就是把别人的眼光当成自己生活的唯一标准。到最…

centos版本的EDA虚拟机搭建2

这次教程主要介绍centos的必备软件的安装。 0、参考博客 1、VMware下CentOS 7虚拟机的安装 2、搭建属于自己的数字IC EDA环境&#xff08;二&#xff09;&#xff1a;搭建Centos的基本使用环境和工具 3、cenos7基本配置 1、git安装 sudo yum install -y git2、gvim安装 su…

从大型语言模型LLM走向人工通用智能AGI的改进方向(public)

从大型语言模型走向人工通用智能AGI 返回论文和资料目录 1.导读 这篇博客主要基于《Sparks of Artificial General Intelligence: Early experiments with GPT-4》文中第9和第10节、以及我自己对当前LLM和AGI的理解。给出大型语言模型走向AGI时 改进的方向。 2.14个问题及改…

详解:阿里邮箱_阿里企业邮箱_阿里邮箱企业版

阿里邮箱是阿里云自主研发的&#xff0c;基于飞天平台自主研发的云原生分布式邮箱系统&#xff0c;阿里邮箱提供免费版、标准版、尊享版和集团版&#xff0c;企业邮箱版本不同支持的账号数也不同&#xff0c;共享网盘容量和个人网盘容量均不同&#xff0c;阿里云百科来详细介绍…

工厂方法模式(Factory Method)

别名 虚拟构造函数&#xff08;Virtual Constructor&#xff09;。 定义 工厂方法是一种创建型设计模式&#xff0c;其在父类中提供一个创建对象的方法&#xff0c;允许子类决定实例化对象的类型。 前言 1. 问题 假设你正在开发一款物流管理应用。最初版本只能处理卡车运…

【85 backtrader-cs因子测试的一些高级技巧-2】使用cython、c语言和c++加速某些函数的计算

在上一篇文章:【85 backtrader-cs因子测试的一些高级技巧】使用numba加速某些函数的计算中,使用了numba改进某些函数,实现加速,在这一篇文章中,尝试接着上一篇文章的主题,继续尝试用cython,c语言和c++尝试改进decayliear函数的计算速度。 结论: 从图上似乎可以得到下面…

Java程序性能优化技巧

1、慎用异常 在Java软件开发中&#xff0c;经常使用 try-catch 进行错误捕获&#xff0c;但是&#xff0c;try-catch 语句对系统性能而言是非常糟糕的。虽然在一次 try-catch中&#xff0c;无法察觉到它对性能带来的损失&#xff0c;但是&#xff0c;一旦try-catch被应用于循环…

从零开始 verilog 以太网交换机(五)帧合路单元的设计与实现

从零开始 verilog 以太网交换机&#xff08;五&#xff09;帧合路单元的设计与实现 &#x1f508;声明&#xff1a; &#x1f603;博主主页&#xff1a;王_嘻嘻的CSDN主页 &#x1f9e8; 从零开始 verilog 以太网交换机系列专栏&#xff1a;点击这里 &#x1f511;未经作者允许…

07-歌词滚动效果

现在学习的代码工作中不一定会需要&#xff0c;如果有&#xff0c;也已经做成了产品和库&#xff0c; 前端重点是创造&#xff0c;面试官考验你的能力是会提出最刁钻的问题给你的。 项目效果 原生JS效率是最高的&#xff0c;框架只是提高代码的可读性 favico图标添加 两种方…

一个工具类让你彻底解决bean深拷贝

深拷贝是我们在代码开发当中经常需要使用到的&#xff0c;但是市面上的对象拷贝方法&#xff0c;比如spring自带的&#xff0c;或者其他工具类带的对象拷贝&#xff0c;大部分都是浅拷贝&#xff0c;根本无法满足咱们的业务需求&#xff0c;我们就只能对里面的引用对象进行专门…

guacamole 纯web rdp预研:web应用程序部分

文章目录 web rdp预研 web应用程序部分预研目的相关基础Web应用结构&#xff08;框架&#xff09;配置tomcat运行web项目与前端交互原理问题整理Java web基础知识Java web调试预研结论 web rdp预研 web应用程序部分 ⭐️来自很多年前的笔记&#xff0c;只是一个归档&#xff0…

面向对象【成员变量与局部变量、方法声明与作用】

文章目录 成员变量局部变量成员变量与局部变量的区别 方法方法的作用方法的声明 成员变量 Java中的成员变量是指类中声明的变量&#xff0c;也称为实例变量或属性。它们与方法一样属于类的成员&#xff0c;不同之处在于&#xff0c;它们存储在对象(堆)中而不是栈中&#xff0c;…

基于灰色预测模型的负荷预测(matlab程序)

0.代码链接 基于灰色预测模型的负荷预测&#xff08;matlab程序&#xff09;资源-CSDN文库 1.简述 灰色预测是一种对含有不确定因素的系统进行预测的方法。灰色预测通过鉴别系统因素之间发展趋势的相异程度&#xff0c;即进行关联分析&#xff0c;并对原始数据进行生成处理来…

python:并发编程(二十六)

前言 本文将和大家一起探讨python并发编程的实际项目&#xff1a;win图形界面应用&#xff08;篇八&#xff0c;共八篇&#xff09;&#xff0c;系列文章将会从零开始构建项目&#xff0c;并逐渐完善项目&#xff0c;最终将项目打造成适用于高并发场景的应用。 本文为python并…

ADAS(高级驾驶员辅助系统)

什么是 ADAS ADAS —— 高级驾驶员辅助系统&#xff0c;包含一系列硬件和软件组件&#xff0c;自动起到驾驶员的多项作用。目前&#xff0c;常见的车辆 ADAS 功能包括自适应巡航控制、盲点检测、变道检测(车道偏离警告系统)、自动车道跟随和自动紧急制动、泊车。 L0到L2称为AD…

测试用例详解(强,硬,牛)

目录&#xff1a; 测试用例价值与体系黑盒测试方法论-等价类黑盒测试方法论-边界值黑盒测试方法论-因果图黑盒测试方法论-判定表黑盒测试方法论-场景法测试用例基础概念测试用例设计与评审面试测试测试用例设计搜索功能测试用例设计 1.测试用例价值与体系 测试用例概念测试…

【MQTT】| 搭建——在云服务器上搭建MQTT服务器

系列文章目录 【MQTT】| 搭建——在云服务器上搭建MQTT服务 失败了也挺可爱&#xff0c;成功了就超帅。 文章目录 前言1. EMQX简介2. EMQX部署3. EMQX一些操作指令3.1 启动EMQX3.2 停止EMQX3.3 检查EMQX运行状态3.4 卸载EMQX 4. EMQX设置4.1 进入EMQX控制面板 5. EMQX测试5.1…

模型评估 (Model Assessment)

1.模型评估 (Model Assessment) 笔记来源于《白话机器学习的数学》 我们训练好模型后&#xff0c;要对知道这个模型到底好不好&#xff0c;定量描述这个模型好坏就是模型评估 把获取的全部训练数据分成两份&#xff1a;一份用于测试&#xff0c;一份用于训练。然后用前者来评估…