重学java 79.JDK新特性 ⑤ JDK8之后的新特性

news2024/12/27 1:16:23

别怕失败,大不了重头再来

                                                   —— 24.6.20

一、接口的私有方法

Java8版本接口增加了两类成员:

        公共的默认方法
        公共的静态方法

Java9版本接口又新增了一类成员:

        私有的方法

为什么IDK1.9要允许接口定义私有方法呢?

        因为我们说接口是规范,规范是需要公开让大家遵守的

        私有方法::因为有了默认方法和静态方法这样具有具体实现的方法,那么就可能出现多个方法由共同的代码可以抽取,而这些共同的代码抽取出来的方法又只希望在接口内部使用,所以就增加了私有方法。

接口

public interface USB {
    private void open(){
        System.out.println("私有非静态方法");
    }

    private static void close(){
        System.out.println("私有静态方法");
    }

    // 定义一个默认方法,去调用私有方法
    public default void methodDef(){
        open();
        close();
    }
}

实现类

public class UsbImpl implements USB{
    public static void main(String[] args) {
        new UsbImpl().methodDef();
    }
}

测试方法

public class Demo329UsbImple {
    public static void main(String[] args) {
        new UsbImpl().methodDef();
    }
}

二、钻石操作符与匿名内部类结合

        自Java 9之后我们将能够与匿名实现类共同使用钻石操作符(泛型),即匿名实现类也支持类型自动推断 

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

public class Demo330Combine {
    public static void main(String[] args) {
        ArrayList<Person> list = new ArrayList<>();
        list.add(new Person("张三",10));
        list.add(new Person("李四",8));
        list.add(new Person("王五",20));

        Collections.sort(list,new Comparator<>() {
            // 从jdk9开始可以省略参数中的泛型
            @Override
            public int compare(Person o1, Person o2) {
                return o1.getAge()-o2.getAge();
            }
        });

        System.out.println(list);
    }
}

Javà 8的语言等级编译会报错:"'<>' cannot be used with anonymous classes。”java 9及以上版本才能编译和运行正常。

三、try...catch的升级

之前我们讲过JDK 1.7引入了trywith-resources的新特性,可以实现资源的自动关闭,此时要求:

        该资源必须实现java.io.Closeable接口

        在try子句中声明并初始化资源对象

        该资源对象必须是final

try(IO流对象1声明和初始化;IO流对象2声明和初始化){
    可能出现异常的代码
}catch(异常类型 对象名){
    异常处理方案
}

jdk1.9后,对trywith- resources的语法进行升级

        该资源必须实现java.io.Closeable接口

        在try子句中声明并初始化资源对象,也可以直接使用已初始化的资源对象

        该资源对象必须是final

语法

IO流对象1声明和初始化;

IO流对象2声明和初始化;

try(IO流对象1;IO流对象2){

        可能出现异常的代码

}catch(异常类型 对象名){

异常处理方案

}
import java.io.File;
import java.io.FileWriter;
import java.io.FilterWriter;

public class Demo331TryCatchUp {
    public static void main(String[] args) throws Exception {
        //method01();
        method02();
    }

    /**
     * jdk8之前
     */
    private static void method01()  {
        try(FileWriter fw = new FileWriter("AllWillBest_Java\\io.txt")){
            fw.write("一切都会好的");
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    /**
     * JDk9开始,为了减轻try的压力,可以将对象放到外面去new,然后将对象名放在try中
     * 而且依然能够自动刷新和关流
     */
    private static void method02() throws Exception {
        FileWriter fw = new FileWriter("AllWillBest_Java/io.txt");
        try(fw){
            fw.write("你好");
        }catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}

四、局部变量的类型自动推断

        jdk10之前,我们定义局部变量都必须要明确教据的数据类型,但是到了!DK10,出现了一个最为重要的特性,就是局部变量类型推断,顾名思义,就是定义局部变量时,不用先确定具体的数据类型了,可以直接根据具体数据推断出所属的数据类型。

        var 变量名 = 值;

public class Demo332Var {
    public static void main(String[] args) {
        var i = 10;
        System.out.println(i);

        var j = "一切都会好的";
        System.out.println(j);

        var arr = new int[]{1, 2, 3, 4, 5};
        for (int i1 : arr) {
            System.out.print(i1+" ");
        }
    }
}

五、switch表达式

1.Java12的switch表达式

Java 12对switch语句进行了扩展,将其作为增强版的switch语句或称为switch表达式,可以写出更加简化的代码。

        允许将多个case语句合并到一行,可以简洁、清晰也更加优雅地表达逻辑分支。
        可以使用->代替:
                写法默认省略break语句,避免了因少写break语句而出错的问题。
                写法在标签右侧的代码段可以是表达式、代码块或 throw语句。
                写法在标签右侧的代码块中定义的局部变量,其作用域就限制在代码块中,而不是延到整个switch结构。
        同一个switch结构中不能混用“一>"和”:",否则会有编译错误。使用字符":",这时fall-through规则依然有效,即不能省略原有的break语句。":"的写法表示继续使用传统switch语法。

案例需求:判断季节

        请使用switch-case结构实现根据月份输出对应季节名称。例如,3~5月是春季,6~8月是夏季,9~11月是秋季,12~2月是冬季。

public class Demo333Switch {
    public static void main(String[] args) {
        method01();
        method02();
    }

    private static void method02(){
        int month = 9;
        switch (month) {
            case 12,1,2 ->
                    System.out.println("冬季");
            case 3,4,5 ->
                    System.out.println("春季");
            case 6,7,8 ->
                    System.out.println("夏季");
            case 9,10,11 ->
                    System.out.println("秋季");
        }
    }

    private static void method01() {
        int month = 5;
        /**
         * 用: 方式,改正后不写break依然会case穿透,如果想不加break也不穿透,将case后的:改为->
         */
        switch (month) {
            case 12,1,2:
                System.out.println("冬季");
                break;
            case 3,4,5:
                System.out.println("春季");
                break;
            case 6,7,8:
                System.out.println("秋季");
                break;
            case 9,10,11:
                System.out.println("冬季");
                break;
            default:
                System.out.println("没有这个季节,您输入错误");
        }
    }
}

2.Java13的switch表达式

        Java 13提出了第二个switch表达式预览,引入了yield语句,用于返回值。这意味着,switch表达式(返回值)应该使用yield语句,switch语句(不返回值)应该使用break语句。

        案例需求:判断季节

public class Demo333Switch {
    public static void main(String[] args) {
        method01();
        method02();
        method03();
        method04();
    }

    /**
     * jdk13之后,
     */
    private static void method04() {
        int month = 7;
        var season = switch (month) {
            case 12,1,2 -> {
                yield "冬季";
            }
            case 3,4,5 -> {
                yield "春季";
            }
            case 6,7,8 -> {
                yield "夏季";
            }
            case 9,10,11 -> {
                yield "秋季";
            }
            default -> {
                yield "错误输入";
            }
        };
        System.out.println("season = " + season);
    }


    /**
     * jdk13之前想要拿到switch结果,需要定义一个变量,然后为其赋值
     */
    private static void method03() {
        int month = 11;
        String season = "";
        switch (month) {
            case 12,1,2:
                season = "冬季";
                break;
            case 3,4,5:
                season = "春季";
                break;
            case 6,7,8:
                season = "夏季";
                break;
            case 9,10,11:
                season = "秋季";
                break;
            default:
                season="错误输入";
                break;
        }
        System.out.println(season);
    }

    private static void method02(){
        int month = 9;
        switch (month) {
            case 12,1,2 ->
                    System.out.println("冬季");
            case 3,4,5 ->
                    System.out.println("春季");
            case 6,7,8 ->
                    System.out.println("夏季");
            case 9,10,11 ->
                    System.out.println("秋季");
        }
    }

    private static void method01() {
        int month = 5;
        /**
         * 用: 方式,改正后不写break依然会case穿透,如果想不加break也不穿透,将case后的:改为->
         */
        switch (month) {
            case 12,1,2:
                System.out.println("冬季");
                break;
            case 3,4,5:
                System.out.println("春季");
                break;
            case 6,7,8:
                System.out.println("夏季");
                break;
            case 9,10,11:
                System.out.println("秋季");
                break;
            default:
                System.out.println("没有这个季节,您输入错误");
                break;
        }
    }
}

六、文本块

        预览的新特性文本块在Java 15中被最终确定下来,Java 15之后我们就可以放心使用该文本块了。

        JDK 12引入了Raw String Literals特性,但在其发布之前就放弃了这个特性。这个JEP与引入多行字符串文字(文本块)在意义上是类似的。Java13中引入了文本块(预览特性),这个新特性跟Kotlin中的文本块是类似的。

现实问题

        在java中,通常需要使用String类型表达HTML,XML,SQL或ISON等格式的字符串,在进行字符串赋值时需要进行转义和连接操作,然后才能编译该代码,这种表达方式难以阅读并且难以维护。

        文本块就是指多行字符串,例如一段格式化后的XML、JSON等。而有了文本块以后,用户不需要转义,java能自动搞定。因此,文本块将提高Java程序的可读性和可写性。

目标

        简化跨越多行的字符串,避免对换行等特殊字符进行转义,简化编写Java程序。.

        增强Java程序中字符串的可读性。

举例

package S111NewJdk;

public class Demo334TextPiece {
    public static void main(String[] args) {
        String s = "<html>\n" +
                "   <body>\n" +
                "       <p>一切都会好的,我一直相信</p>\n" +
                "   </body>\n" +
                "</html>";
        System.out.println(s);

        System.out.println("——————————————————————————————————————");

        String s1 = """
                       <html>
                          <body>
                              <p>一切都会好的,我一直相信</p>
                          </body>
                       </html>
                       """;
        System.out.println(s1);
    }
}

七、instanceof模式匹配

        instanceof的模式匹配在JDK14、15中预览,在JDK16中转正。有了它就不需要编写先通过instanceof判断再强制转换的代码。

多态重写进行判断

public class Demo335Instanceof {
    public static void main(String[] args) {
        Dog dog = new Dog();
        method(dog);
        Cat cat = new Cat();
        method(cat);
    }

    public static void method(Animal animal){
        if(animal instanceof Dog){
            Dog dog = (Dog)animal;
            dog.eat();
            dog.lookDoor();
        } else if (animal instanceof Cat) {
            Cat cat = (Cat)animal;
            cat.eat();
            cat.catchMouse();
        }
    }
}

instanceof

public class Demo335Instanceof {
    public static void main(String[] args) {
        Dog dog = new Dog();
        method(dog);
        Cat cat = new Cat();
        method(cat);
        method01(dog);
        method01(cat);
    }

    public static void method01(Animal animal) {
        if (animal instanceof Dog dog) {
            dog.eat();
            dog.lookDoor();
        }else if (animal instanceof Cat cat) {
            cat.eat();
            cat.catchMouse();
        }
    }

    public static void method(Animal animal){
        if(animal instanceof Dog){
            Dog dog = (Dog)animal;
            dog.eat();
            dog.lookDoor();
        } else if (animal instanceof Cat) {
            Cat cat = (Cat)animal;
            cat.eat();
            cat.catchMouse();
        }
    }
}

八、Record类

        Record类在JDK14、15预览特性,在JDK16中转正。
        record是一种全新的类型,它本质上是一个 final类,同时所有的属性都是 final修饰,它会自动编译出get、hashCode 、比较所有属性值的equals、tostring,等方法,减少了代码编写量。使用 Record 可以更方便的创建一个常量类。

注意:

        Record只会有一个全参构造

        重写的equals方法比较所有属性值

        可以在Record声明的类中定义静态字段、静态方法或实例方法(非静态成员方法),。不能       

        Record声明的类中定义实例字段(非静态成员变量);

        类不能声明为abstract;        

        不能显式的声明父类,默认父类是java.lang.Record类

        因为Record类是一个 final类,所以也没有子类等

示例

import S106Lombok.Person;
import org.w3c.dom.ls.LSOutput;

public class Demo336Record {
    public static void main(String[] args) {
        PersonR personR = new PersonR("张三");
        PersonR personR1 = new PersonR("张三");
        System.out.println(personR.equals(personR1));
        // 提供了比较对象的equals方法
    }
}

九、密封类

        其实很多语言中都有密封类的概念,在]ava语言中,也早就有密封类的思想,就是final修饰的类,该类不允许被继承。而从IDK15开始,针对 密封类进行了升级。

        java 15通过密封的类和接口来增强|ava编程语言,这是新引入的预览功能并在|ava16中进行了二次预览,并在ava17最终确定下来。这个预览功能用于限制超类的使用,密封的类和接口限制其他可能继承或实现它们的其他类或接口。

【修饰符】sealed class 密封类【extends 父类】【implements 父接口】permits 子类{

}

【修饰符】 sealed interface 接口【extends 父接口们】permits 实现类{
}

密封类用 sealed 修饰符来描述,

使用 permits 关键字来指定可以继承或实现该类的类型有哪些

一个类继承密封类或实现率封接口,该类必须是sealed、non-sealed、final修饰的

sealed修饰的类或接口必须有了类或实现类

public sealed class AnimalS permits DogS,CatS {
}
public non-sealed class DogS extends AnimalS{
}
public non-sealed class CatS extends AnimalS{
}

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

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

相关文章

AI 大模型企业应用实战(08)-LangChain用prompts模板调教LLM的输入输出

超越chatGPT:学习使用prompts模板来调教LLM的输入输出&#xff0c;打造自己版本的"贾维斯" 1 Model I/O&#xff1a;LLM的交互接口 任何语言模型应用程序的核心要素都是......模型。LangChain 为您提供了与任何语言模型连接的构件。 即 Prompts -> Language mod…

免费ddns工具,快解析DNS解析使用教程

DDNS&#xff08;Dynamic Domain Name Server&#xff09;,中文叫动态域名解析&#xff0c;主要用于没有固定公网ip的网络环境下&#xff0c;使用一个固定的域名&#xff0c;解析动态变化的ip地址&#xff0c;达到远程访问的目的。 众所周知&#xff0c;目前公网ip资源非常紧缺…

昇思25天学习打卡营第6天|使用静态图加速

学AI还能赢奖品&#xff1f;每天30分钟&#xff0c;25天打通AI任督二脉 (qq.com) 背景介绍 AI编译框架分为两种运行模式&#xff0c;分别是动态图模式以及静态图模式。MindSpore默认情况下是以动态图模式运行&#xff0c;但也支持手工切换为静态图模式。两种运行模式的详细介…

MySQL数据库(三):读取数据库数据

上一节&#xff0c;我们介绍了数据库的基本操作&#xff0c;以及最后演示了如何使用库来连接数据库&#xff0c;在实际应用中&#xff0c;我们通常需要按照指定的条件对数据库进行操作&#xff0c;即增删改查操作&#xff0c;这是非常重要的&#xff01;这一节我们继续通过一个…

【电源专题】案例:电量计遇到JEITA充电芯片,在高温下无法报百怎么办?

在使用电量计芯片时,我们期望的是在产品工作温度下、在产品最低和正常充电电流下都要能报百。 所谓报百,就是电量计RSOC(电量百分比)能到达100%。这看起来简单,如果是常规的操作的话,那么电压达到充电截止要求、电流达到充电截止要求、容量累积变化满足要求,RSOC=100%肯…

数据清洗!即插即用!异常值、缺失值、离群值处理、残差分析和孤立森林异常检测,确保数据清洗的全面性和准确性,MATLAB程序!

适用平台&#xff1a;Matlab2021版及以上 数据清洗是数据处理和分析中的一个关键步骤&#xff0c;特别是对于像风电场这样的大型、复杂数据集。清洗数据的目的是为了确保数据的准确性、一致性和完整性&#xff0c;从而提高数据分析的质量和可信度&#xff0c;是深度学习训练和…

面向卫星遥感的红外微小舰船目标检测方法:MTU-Net

论文简介 空间红外微小舰船检测旨在从地球轨道卫星所拍摄的图像中识别并分离出微小舰船。由于图像覆盖面积极其广大&#xff08;如数千平方公里&#xff09;&#xff0c;这些图像中的候选目标相比空中或地面成像设备观测到的目标&#xff0c;尺寸更小、亮度更低且变化更多。现有…

详细分析Springmvc中的@ModelAttribute基本知识(附Demo)

目录 前言1. 注解用法1.1 方法参数1.2 方法1.3 类 2. 注解场景2.1 表单参数2.2 AJAX请求2.3 文件上传 3. 实战4. 总结 前言 将请求参数绑定到模型对象上&#xff0c;或者在请求处理之前添加模型属性 可以在方法参数、方法或者类上使用 一般适用这几种场景&#xff1a; 表单…

图形编辑器基于Paper.js教程03:认识Paper.js中的所有类

先来认一下Paper的资源对象&#xff0c;小弟有哪些&#xff0c;有个整体的认识。认个脸。 在Paper.js的 官方文档中类大致有如下这些&#xff1a; 基类&#xff1a; ProjectViewItemPointToolSizeSegmentRectangleCurveCurveLocationMatrixColorStyleTweenToolEventGradient…

用于射频功率应用的氮化铝电阻元件

EAK推出了新的厚膜氮化铝 &#xff08;AlN&#xff09; 电阻器和端接系列&#xff0c;以补充公司现有的产品。传统上&#xff0c;射频功率电阻元件采用氧化铍&#xff08;BeO&#xff09;陶瓷材料作为陶瓷基板;然而&#xff0c;由于国际上要求从产品中去除BeO的压力&#xff0c…

26.3 Django路由层

1. 路由作用 在Django中, URL配置(通常称为URLconf)是定义网站结构的基础, 它充当着Django所支撑网站的目录. URLconf是一个映射表, 用于将URL模式(patterns)映射到Python的视图函数或类视图上. 这种映射机制是Django处理HTTP请求的基础, 它决定了当客户端发送请求时, Django如…

RabbitMQ实践——临时队列

临时队列是一种自动删除队列。当这个队列被创建后&#xff0c;如果没有消费者监听&#xff0c;则会一直存在&#xff0c;还可以不断向其发布消息。但是一旦的消费者开始监听&#xff0c;然后断开监听后&#xff0c;它就会被自动删除。 新建自动删除队列 我们创建一个名字叫qu…

MM-LLM:CogVLM解读

在图文多模态模型中&#xff0c;范式是图像的编码器、文本编码器、模态融合器。也就是不同模态特征抽取加模态对齐。 这部分可以看李沐的精讲 在大模型里的范式在也是如此&#xff0c;目前的工作大部分都专注于怎么拉齐不同模态。 该论文的动机&#xff08;背景&#xff09;&…

Bev系列算法总结

1. LSS-Based 1.1 BevDet 通过Lift splat 对于2d 特征中的每个pixel(特征点)估计一个3d的深度分布,这样就可以将2d点投影到3d空间上。这样就可以拿到UVD个3d特征点,然后通过voxel pooling 对高度方向拍平, 这样就得到Bev空间的特征图。然后再通过Bev encoder以及任务头。 …

vue3-openlayers 使用tianditu,wmts和xyz等source加载天地图切片服务

本篇介绍一下使用vue3-openlayers加载天地图切片&#xff0c;三种方法&#xff1a; 使用tianditu&#xff08;ol-source-tianditu内部实现其实用的wmts&#xff09;使用wmts&#xff08;ol-source-wmts&#xff09;使用xyz&#xff08;ol-source-xyz&#xff09; 1 需求 vue…

ArkTS开发系列之导航 (2.6 图形)

上篇回顾&#xff1a;ArkTS开发系列之导航 (2.5.2 页面组件导航&#xff09; 本篇内容&#xff1a; 显示图片、自定义图形和画布自定义图形的学习使用 一、知识储备 1. 图片组件&#xff08;Image&#xff09; 可以展示jpg 、png 、svg 、gif等各格式的网络和本地资源文件图…

潜艇伟伟迷杂交版植物大战僵尸2024最新免费安卓+ios苹果+iPad分享

嗨&#xff0c;亲爱的游戏迷们&#xff01;今天我要给你们种草一个超有趣的游戏——植物大战僵尸杂交版。这款游戏不仅继承了原有经典游戏的核心玩法&#xff0c;还加入了许多创新元素&#xff0c;让玩家能够体验到前所未有的乐趣。快来跟随我一起探索这个神奇的世界吧&#xf…

自然语言处理领域的明星项目推荐:Hugging Face Transformers

在当今人工智能与大数据飞速发展的时代&#xff0c;自然语言处理&#xff08;NLP&#xff09;已成为推动科技进步的重要力量。而在NLP领域&#xff0c;Hugging Face Transformers无疑是一个备受瞩目的开源项目。本文将从项目介绍、代码解释以及技术特点等角度&#xff0c;为您深…

线程封装,互斥

文章目录 线程封装线程互斥加锁、解锁认识接口解决问题理解锁 线程封装 C/C代码混编引起的问题 此处pthread_create函数要求传入参数为void * func(void * )类型,按理来说ThreadRoutine满足,但是 这是在内类完成封装,所以ThreadRoutine函数实际是两个参数,第一个参数Thread* …

Python 围棋

效果图 完整代码 源码地址&#xff1a;Python 围棋 # 使用Python内置GUI模块tkinter from tkinter import * # ttk覆盖tkinter部分对象&#xff0c;ttk对tkinter进行了优化 from tkinter.ttk import * # 深拷贝时需要用到copy模块 import copy import tkinter.me…