Java - JDK17语法新增特性(如果想知道Java - JDK17语法新增常见的特性的知识点,那么只看这一篇就足够了!)

        前言:Java在2021年发布了最新的长期支持版本:JDK 17。这个版本引入了许多新的语法特性,提升了开发效率和代码可读性。本文将简要介绍一些常见的新特性,帮助开发者快速掌握并应用于实际开发中。


✨✨✨这里是秋刀鱼不做梦的BLOG

✨✨✨想要了解更多内容可以访问我的主页秋刀鱼不做梦-CSDN博客

先让我们看一下本文大致的讲解内容:

1.yield关键词

        ——先让我们来了解一下yield关键词的作用:

yield关键字,用于增强switch表达式,使其能够返回值。yield允许switch表达式在不同的分支中返回特定的值,并将其赋给变量。

先让我们来看一个正常的switch的例子:

public class Test {
    public static void main(String[] args) {
        String data = "one";
        int result = 0; // 接收数据的返回值
        switch (data) {
            case "one":
                result = 1; // 为result重新赋值
                break;
            case "two":
                result = 2; // 为result重新赋值
                break;
            default:
                result = -1; // 为result重新赋值
                break;
        }
        System.out.println(result);
    }
}

代码分析:

  1. 定义类和主方法:代码定义了一个名为Test的类,并包含一个main方法,这是程序的入口点。

  2. 初始化变量:声明并初始化了两个变量,dataresultdata被赋值为字符串"one",result被初始化为0。

  3. switch语句:

    • 根据data的值进行判断。

    • 如果data的值是"one",则执行result = 1;,并通过break跳出switch语句。

    • 如果data的值是"two",则执行result = 2;,并通过break跳出switch语句。

    • 如果data的值不是"one"或"two",则执行default块,将result赋值为-1,并通过break跳出switch语句。

  4. 输出结果:通过System.out.println(result);result的值输出到控制台。

现在让我们将上述的代码进行简化,简化后的switch:

public static void main(String[] args) {
    String data = "one";
    int result = switch (data) {
        case "one" -> 1;
        case "two" -> 2;
        default -> -1;
    };
    System.out.println(result);
}

我们发现我们可以使用->来返回switch语句的值,当然有读者会问了,这和我们讲解的yield有什么关系呢?,接下来让我们将上述代码转换为yield的形式:

public static void main(String[] args) {
    String data = "one" ;
    int result = switch (data) {
        case "one" : yield 1;
        case "two": yield 2;
        default : yield -1;
    };
    System.out.println(result) ;
}

我们可以发现我们也可以使用yield来返回switch的值,这就是yield语句。

2.var关键词

        var是Java 10中引入的一个新特性,用于局部变量类型推断。它允许编译器在编译时自动推断变量的类型,从而简化代码书写和增强代码可读性。

        接下来我们直接使用实例来进行讲解:

以下是一个使用var的示例:

import java.util.ArrayList;

public class VarExample {
    public static void main(String[] args) {
        // 使用var声明整型变量
        var number = 10;
        System.out.println("Number: " + number);

        // 使用var声明字符串变量
        var text = "Hello, Java 10!";
        System.out.println("Text: " + text);

        // 使用var声明集合
        var list = new ArrayList<String>();
        list.add("Apple");
        list.add("Banana");
        System.out.println("List: " + list);

        // 使用var声明迭代器
        for (var item : list) {
            System.out.println("Item: " + item);
        }
    }
}

        从上述的代码我们可以看到,我们使用var关键词来声明变量,其会自动的推断类型。这大大的方便了我们声明变量。

注意:

        虽然var关键词可以推断出变量的类型,但是不要什么时候都使用var关键词来声明变量,一般在类型名称非常长的时候,例如泛型,我们会使用var来简化代码。

例如:

public static void main(String[] args) {
    Map<String, List<Map<Integer, String>>> complexMap = new HashMap<String,
                List<Map<Integer, String>>>();

    //使用var关键词进行简化 
    var complexMap2 = new HashMap<String, List<Map<Integer, String>>>();
}

我们可以发现这样我们的代码繁琐度大大的简化了。

注意事项:

  • var只能用于局部变量声明,不能用于成员变量、方法参数或返回类型。

  • 变量必须在声明时初始化,因为编译器需要根据初始化值来推断变量类型。

  • var不能用于没有初始化值的变量声明。

  • var不能用于null初始化,因为无法推断类型。

以上就是Java中的var关键词的使用了。

3.密封类 - sealed

        在讲解sealed关键词之前,先让我们讲解一下什么是密封类:

        密封类(Sealed Classes)是一项语言特性,旨在更好地控制类层次结构中的继承关系。通过使用密封类,开发者可以明确指定哪些类可以继承某个类,从而增强类型安全性和代码可维护性。

我们知道,在Java中使用final修饰的类为密封类,其作用就是不能被其他类所继承,如果被继承就会报错,例如:

// 定义一个final类
public final class FinalClass {
    private String message;

    public FinalClass(String message) {
        this.message = message;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

// 尝试继承final类
public class SubClass extends FinalClass {  // 这行会导致编译错误
    public SubClass(String message) {
        super(message);
    }
}

        当然,在JDK17中提供了一个新的关键字: sealed 。它允许你显式地列出可以扩展某个类或实现某个接口的类,从而增强了类型安全性和可维护性。

     

         —— 那么怎么使用sealed关键词呢?

     

使用sealed关键字的步骤如下:

  1. (1)声明一个sealed类或接口。

  2. (2)使用permits关键字明确允许哪些类可以继承该sealed类或接口。

  3. (3)被允许的子类必须是finalsealed,或non-sealed的。

让我们直接使用案例来帮助你进行理解:(代码如下)

// 定义一个sealed类
public sealed class Shape permits Circle, Rectangle, Square {
    // 声明一个抽象方法area,要求任何继承Shape的子类必须实现这个方法
    public abstract double area();
}

// 定义一个final子类
public final class Circle extends Shape {
    // 声明一个私有的最终变量radius,用于存储圆的半径
    private final double radius;

    // Circle类的构造方法,接收一个半径参数并初始化radius
    public Circle(double radius) {
        this.radius = radius;
    }

    // 实现Shape类中声明的抽象方法area,计算并返回圆的面积
    @Override
    public double area() {
        return Math.PI * radius * radius;
    }
}

// 定义一个sealed子类
public sealed class Rectangle extends Shape permits FilledRectangle {
    // 声明两个私有的最终变量width和height,用于存储矩形的宽和高
    private final double width;
    private final double height;

    // Rectangle类的构造方法,接收矩形的宽和高参数并初始化width和height
    public Rectangle(double width, double height) {
        this.width = width;
        this.height = height;
    }

    // 实现Shape类中声明的抽象方法area,计算并返回矩形的面积
    @Override
    public double area() {
        return width * height;
    }
}

// 定义一个non-sealed子类
public non-sealed class Square extends Shape {
    // 声明一个私有的最终变量side,用于存储正方形的边长
    private final double side;

    // Square类的构造方法,接收一个边长参数并初始化side
    public Square(double side) {
        this.side = side;
    }

    // 实现Shape类中声明的抽象方法area,计算并返回正方形的面积
    @Override
    public double area() {
        return side * side;
    }
}

// 进一步定义一个final子类
public final class FilledRectangle extends Rectangle {
    // 声明一个私有的最终变量color,用于存储填充矩形的颜色
    private final String color;

    // FilledRectangle类的构造方法,接收矩形的宽、高和颜色参数,并调用父类Rectangle的构造方法进行初始化
    public FilledRectangle(double width, double height, String color) {
        super(width, height);
        this.color = color;
    }

    // 添加一个额外的方法getColor,用于获取填充矩形的颜色
    public String getColor() {
        return color;
    }
}

在这个例子中:

1. Shape是一个sealed类,只有CircleRectangleSquare可以继承它。

2. Circle是一个final类,不能被进一步继承。

3. Rectangle是一个sealed类,只有FilledRectangle可以继承它。

4. Square是一个non-sealed类,可以被进一步继承

并且我们要注意:

        1. sealed修饰的类必须要有子类;

        2. 未被permits 允许的类型,则没办法继承;

        3. 子类使用final修饰则不可以继承发生继承;

        4. 子类使用 non-sealed 关键字修饰。表示不限制,任何类都可以继承;

        5. 子类使用sealed关键词的可以继承发生继承;

这样我们就大致的了解了sealed关键词了。

4.接口中的私有方法

        在接口中的私有方法常常用于对接口中的default修饰的方法和静态方法进行辅助,将其内部的代码进行封装简化。

例如:

interface HelloService {
    public void sayHello();
    // 默认方法
    default void saySomething(){
        syaEngHello();
        sayHello();
    };
    // 私有方法
    private void syaEngHello(){
        System.out.println("Hello!");
    }

        接口的私有方法为Java语言引入了更多的灵活性和功能性,可以帮助编写更干净、更模块化的代码,提升了接口的设计和实现的效率和质量。

        这就是Java中接口中的私有方法的使用。

5.instanceof关键词

        在Java中,instanceof是一个关键字,用于测试一个对象是否是一个类的实例或者是其子类的实例。它的语法形式如下:

object instanceof type

        其中,object是要检查的对象,type是一个类名或接口名。instanceof操作符的作用是检查object是否是type类型的实例,或者是type类型的子类的实例。它返回一个布尔值,如果objecttype类型或其子类的实例,则返回true;否则返回false

        ——接下来让我们使用一个实例来进行对其进一步理解:

class Animal {
    // Animal 类的成员和方法
}

class Dog extends Animal {
    // Dog 类的成员和方法
}

public class Main {
    public static void main(String[] args) {
        Animal animal = new Dog(); // 创建一个 Dog 对象并赋值给 Animal 类型的变量

        // 使用 instanceof 来检查对象的类型
        if (animal instanceof Dog) {
            System.out.println("animal 是 Dog 类的实例");
        }
        
        if (animal instanceof Animal) {
            System.out.println("animal 是 Animal 类的实例");
        }
        
        if (animal instanceof Object) {
            System.out.println("animal 是 Object 类的实例");
        }
    }
}

解释:

  1. Animal是一个类,DogAnimal的子类。

  2. main方法中,创建了一个Dog对象,并将其赋值给一个Animal类型的变量animal

  3. 使用instanceof关键字,首先检查animal是否是Dog类的实例,结果为true,因为animal确实是Dog类的实例。

  4. 接着检查animal是否是Animal类的实例,同样为true,因为Dog类是Animal类的子类。

  5. 最后检查animal是否是Object类的实例,结果同样为true,因为所有类在Java中最终都是继承自Object类的。

        通过上面的讲解,我相信你已经对Java中instanceof关键词有了一定的理解,那么instanceof关键词有什么用处呢?

instanceof的用途:

  • 类型检查和转换instanceof通常用于在运行时检查对象的类型,以便进行类型转换或根据对象的实际类型执行特定的操作。

  • 条件控制:可以根据对象的类型来决定执行不同的代码路径,以实现多态性和灵活的程序逻辑。

  • 安全性检查:在某些情况下,使用instanceof可以帮助避免类型转换异常(ClassCastException),在进行类型转换之前先检查对象的类型是否符合预期。

这样我们就大致的了解了Java中的instanceof关键词了。


以上就是本篇文章的全部内容了~~~

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

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

相关文章

Mysql笔记-v2【7月5日更新】

零、 help、\h、? 调出帮助 mysql> \hFor information about MySQL products and services, visit:http://www.mysql.com/ For developer information, including the MySQL Reference Manual, visit:http://dev.mysql.com/ To buy MySQL Enterprise support, training, …

深入分析 Android BroadcastReceiver (八)

文章目录 深入分析 Android BroadcastReceiver (八)1. 系统与自定义实现1.1 系统广播机制1.1.1 系统广播的实现原理1.1.2 系统广播的源码分析 1.2 自定义广播机制1.2.1 自定义广播的实现步骤1.2.2 自定义广播的源码分析 2. 广播机制设计的初衷与优势2.1 设计初衷2.2 优势 3. 总…

一文读懂轻量日志收集系统Loki工作原理

Loki 是由 Grafana Labs 开发的日志聚合系统&#xff0c;设计目标是提供一种高效、低成本的日志收集和查询解决方案。与传统的日志系统&#xff08;如 ELK Stack&#xff09;不同&#xff0c;Loki 不会对日志内容进行索引&#xff0c;而是仅对日志的元数据进行索引&#xff0c;…

Python数据分析案例49——基于机器学习的垃圾邮件分类系统构建(朴素贝叶斯,支持向量机)

案例背景 trec06c是非常经典的邮件分类的数据&#xff0c;还是难能可贵的中文数据集。 这个数据集从一堆txt压缩包里面提取出来整理为excel文件还真不容不易&#xff0c;肯定要做一下文本分类。 虽然现在文本分类基本都是深度学习了&#xff0c;但是传统的机器学习也能做。本案…

Lunaproxy与711Proxy的对比与优劣分析

今天我们来深入对比两款在市场上备受关注的代理IP服务&#xff1a;Lunaproxy和711Proxy。接下来&#xff0c;我们将从多个角度对这两款服务进行详细分析&#xff0c;帮助大家做出明智的选择。 优势分析 711Proxy的优势 1. 性价比高&#xff1a;711Proxy提供多种灵活的套餐选…

【电商干货分享】干货速看!电商数据集大全!

数据分析——深入探索中小企业数字化转型&#xff0c;专注提供各行业数据分析干货、分析技巧、工具推荐以及各类超实用分析模板&#xff0c;为钻研于数据分析的朋友们加油充电。 公共参数 名称类型必须描述keyString是调用key&#xff08;必须以GET方式拼接在URL中&#xff0…

C# Application.DoEvents()的作用

文章目录 1、详解 Application.DoEvents()2、示例处理用户事件响应系统事件控制台输出游戏和多媒体应用与操作系统的交互 3、注意事项总结 Application.DoEvents() 是 .NET 框架中的一个方法&#xff0c;它主要用于处理消息队列中的事件。在 Windows 应用程序中&#xff0c;当一…

芯片基识 | 掰开揉碎讲 FIFO(同步FIFO和异步FIFO)

文章目录 一、什么是FIFO二、为什么要用FIFO三、什么时候用FIFO四、FIFO分类五、同步FIFO1. 同步FIFO电路框图2. 同步FIFO空满判断3. 同步FIFO设计代码4. 同步FIFO仿真结果 六、异步FIFO1、异步FIFO的电路框图2 、亚稳态3、打两拍4、格雷码5、如何判断异步FIFO的空满&#xff0…

3D Web轻量化平台HOOPS Web Platform的功能与应用分析

随着3D技术在多个行业的广泛应用&#xff0c;对于3D模型轻量化的需求日益增长。HOOPS Web Platform作为一个先进的3D模型轻量化平台&#xff0c;为开发人员提供了一整套工具来构建和部署基于Web的工程应用程序。本文将分析HOOPS Web Platform的核心功能和它在不同领域的应用情况…

VBA初学:零件成本统计之一(任务汇总)

经过前期一年多对金蝶K3生产任务流程和操作的改造和优化&#xff0c;现在总算可以将零件加工各个环节的成本进行归集了。 原本想写存储过程&#xff0c;通过直接SQL报表做到K3中去的&#xff0c;但财务原本就是用EXCEL&#xff0c;可以方便调整和保存&#xff0c;加上还有一部分…

破解在制品管理不透明难题

在快节奏的现代工业浪潮中&#xff0c;每一个细微的管理环节都直接关系到企业的竞争力与盈利能力。在车间生产中&#xff0c;在制品管理流程不透明是一个常见问题&#xff0c;它可能导致生产效率低下、成本增加、库存积压以及沟通障碍等负面影响。 在制品管理流程不透明&#x…

ETAS工具导入Com Arxml修改步骤

文章目录 前言Confgen之前的更改Confgen之后的修改CANCanIfComComMEcuM修改CanNmCanSMDCMCanTp生成RTE过程报错修改DEXT-诊断文件修改Extract问题总结前言 通讯协议栈开发一般通过导入DBC实现,ETAS工具本身导入DBC也是生成arxml后执行cfggen,本文介绍直接导入客户提供的arxml…

8种数据迁移工具

前言 最近有些小伙伴问我&#xff0c;ETL数据迁移工具该用哪些。 ETL(是Extract-Transform-Load的缩写&#xff0c;即数据抽取、转换、装载的过程)&#xff0c;对于企业应用来说&#xff0c;我们经常会遇到各种数据的处理、转换、迁移的场景。 今天特地给大家汇总了一些目前…

迭代加深——AcWing 170. 加成序列

迭代加深 定义 迭代加深搜索&#xff08;Iterative Deepening Depth-First Search, IDS&#xff09;是一种结合了深度优先搜索&#xff08;DFS&#xff09;和广度优先搜索&#xff08;BFS&#xff09;特点的算法。它通过限制搜索树的深度来控制搜索范围&#xff0c;起初以较小…

CTFShow的RE题(一)

RE2 1.中文字符的显示 2.对文件的读取操作 3.RC4加密 &#xff08;有一点是魔改的&#xff09; 4.enflag.txt文件里面的密文是ASCII编码之后的数据(可以放ida中) 也可以放到 010 里&#xff08;推荐&#xff09; encDH~mqqvqxB^||zllJq~jkwpmvez{ key for i in enc:keychr…

程序员下班为什么不关电脑?难道在偷偷加班?!

不管是周围的程序员朋友还是网上的很多程序员朋友&#xff0c;在下班后都是习惯不关电脑的&#xff0c;关上显示器&#xff0c;拿上手机&#xff0c;快乐下班&#xff01; 那么&#xff0c;为什么程序员下班都不关电脑&#xff1f;难道他们在偷偷加班&#xff1f; 其实&#x…

elasticsearch源码分析-04集群状态发布

集群状态发布 cluster模块封装了在集群层面执行的任务&#xff0c;如集群健康、集群级元信息管理、分片分配给节点、节点管理等。集群任务执行之后可能会产生新的集群状态&#xff0c;如果产生新的集群状态主节点会将集群状态广播给其他节点。 集群状态封装在clusterState中&…

基于Qt实现的PDF阅读、编辑工具

记录一下实现pdf工具功能 语言&#xff1a;c、qt IDE&#xff1a;vs2017 环境&#xff1a;win10 一、功能演示&#xff1a; 二、功能介绍&#xff1a; 1.基于saribbon主体界面框架&#xff0c;该框架主要是为了实现类似word导航项 2.加载PDF放大缩小以及预览功能 3.pdf页面跳转…

Qt 网络编程 网络信息获取操作

学习目标&#xff1a;网络信息获取操作 前置环境 运行环境:qt creator 4.12 学习内容 一、Qt 网络编程基础 Qt 直接提供了网络编程模块,包括基于 TCP/IP 的客户端和服务器相关类,如 QTcpSocket/QTcpServer 和 QUdpSocket,以及实现 HTTP、FTP 等协议的高级类,如 QNetworkRe…

SPIN-Diffusion:自我博弈微调提升文本到图像扩散模型性能

扩散模型作为生成AI的关键实体&#xff0c;已经在多个领域展现出了卓越的能力。然而&#xff0c;现有的扩散模型&#xff0c;如Stable Diffusion和SDXL&#xff0c;通常在预训练阶段后需要进行微调以更好地符合人类偏好。最近&#xff0c;研究者们开始尝试使用强化学习&#xf…