java基础之Java8新特性-方法引入
目录
1.简介
2.方法引入
方法引入遵循规范
方法引入种类
1.静态方法引入
2.对象方法引入
3.实例方法引入
4.构造函数引入
1.简介
方法引用是 Java 8 中引入的另一个重要特性,它提供了一种简洁的语法来直接引用现有方法或构造函数。方法引用可以看作是 Lambda 表达式的一种简化写法,它可以让代码更加简洁易懂。
什么是Lambda 表达式呢?
可以参考另一篇文章:
java基础之Java8新特性-Lambda-CSDN博客
https://blog.csdn.net/qq_62262918/article/details/135395534?spm=1001.2014.3001.5501
示例代码仓库地址:
j8-new-feature: java8新特性示例Demo (gitee.com)
https://gitee.com/mi9688-wine/j8-new-feature
2.方法引入
方法引入遵循规范
当使用方法引用时,被引用的方法的参数类型和返回类型必须与函数式接口的抽象方法相匹配。
方法引入种类
方法引入共有四种分别为静态方法引用(类名::静态方法名)、对象方法引入(类名::实例方法名)、实例方法引入(对象名::方法名)、构造函数引入(类名::new)。
1.静态方法引入
首先我们定义一个函数接口
@FunctionalInterface
public interface MessageInterface {void printMessage(String msg); // 打印内容
}
接着我们调用该接口的printMessage方法就需要重写该接口的该方法。
传统使用匿名内部类的方式
//传统匿名内部类方式new MessageInterface(){@Overridepublic void printMessage(String msg) {System.out.println("打印内容:"+msg);}}.printMessage("hello");
使用Lambda的方式
//使用Lambda((MessageInterface) msg -> System.out.println("打印内容:" + msg)).printMessage("hello");
使用静态方法引入
定义出该静态方法(在某个类里面)这里是图方便直接写在在Test01类里面定义的,然后引用
//定义静态方法public static void staticPrintMessage(String msg){System.out.println("打印内容:"+msg);}
//静态方法引入MessageInterface m=Test01::staticPrintMessage;m.printMessage("hello");
完整示例代码
public class Test01 {public static void main(String[] args) {//传统匿名内部类方式new MessageInterface(){@Overridepublic void printMessage(String msg) {System.out.println("打印内容:"+msg);}}.printMessage("hello");//使用Lambda((MessageInterface) msg -> System.out.println("打印内容:" + msg)).printMessage("hello");//静态方法引入MessageInterface m=Test01::staticPrintMessage;m.printMessage("hello");//简化的写法((MessageInterface) Test01::staticPrintMessage).printMessage("hello");}//定义静态方法public static void staticPrintMessage(String msg){System.out.println("打印内容:"+msg);}
}
可以看到使用方法引入对比Lambda表达式的写法看起来更简短,直接类名::静态方法名;相对于Lambda为何没有参数列表呢?或者说直接省略不写呢?原因很简单就是:被引用的方法的参数类型和返回类型必须与函数式接口的抽象方法相匹配。既然是匹配的那就不需要再写了。
其实也存在一种特例,就是当函数式接口的方法返回类型是void的时候,你定义的被引用方法的返回类型除了是void也可以是任意类型。
比如
@FunctionalInterface
public interface MessageInterface {void printMessage(String msg); // 打印内容
}
public static String staticPrintMessage(String msg){System.out.println("打印内容:"+msg);return msg;}
//静态方法引入MessageInterface m=Test01::staticPrintMessage;m.printMessage("hello");
这样会出现返回类型不一致的情况而不报错,可以正常运行。我理解为就是当函数式接口方法返回类型是void就只需要关注方法的参数和方法的行为,而不需要关注方法的返回值。这里的返回值当作无效的返回值处理了。只有当函数式接口方法返回类型不是void,也就是有返回值时才会关注方法的返回值,并校验是否一致。
如果用说Lambda表达式的方式实现函数式接口,本质就是传入一个匿名函数参数;那用方法引入的方式实现函数式接口本质上也是传入了一个函数参数,只不过这个函数是通过方法引用的方式来实现的,它并不是匿名的。
2.对象方法引入
首先在Message类写个计算内容行数的方法
//计算信息内容行数public int lineCount(){return (this.content.length()/80)+1;}
定义函数接口
@FunctionalInterface
public interface MessageInterface3 {int getMessageRow(Message msg); //获取信息内容行数
}
实现函数接口
public static void main(String[] args) {//LambdaMessageInterface3 m = (msg) -> {return msg.lineCount();};System.out.println(m.getMessageRow(new Message()));System.out.println("----------------------");//对象方法引入MessageInterface3 m1 = Message::lineCount;System.out.println(m1.getMessageRow(new Message()));}
看到这里你可能会思考为何这个lineCount方法不是静态方法却可以直接通过类名::方法名引用呢?
其实前面已经讲过了,就是你通过方法引入实现函数接口就必须保证被引用的方法的参数类型和返回类型必须与函数式接口的抽象方法相匹配,既然匹配了是不是可以省略了。
既然这个函数接口的getMessageRow方法入参是Message对象,那要实现它内部是不是得调用Message对象的 lineCount方法,传统匿名内部类代码:
//匿名内部类MessageInterface3 m0 = new MessageInterface3() {@Overridepublic int getMessageRow(Message msg) {return msg.lineCount();}};System.out.println(m0.getMessageRow(new Message()));
这里使用对象方法引入你就可以理解为把 ” (Message msg) “ 和 ” msg.lineCount(); “ 省略成 ” Message::lineCount; “。
3.实例方法引入
实例方法引入就是new出来该对象,然后引用该实例对象的方法作为函数式接口的方法实现。
public class Test02 {public static void main(String[] args) {//实例化Test02 t = new Test02();//实例方法引用((MessageInterface)t::printMessage).printMessage("Hello");}public void printMessage(String msg){System.out.println("打印内容:"+msg);}
}
4.构造函数引入
实现该函数接口需要重写getMessage方法返回值是Message类型
@FunctionalInterface
public interface MessageInterface2 {Message getMessage();
}
public static void main(String[] args) {//使用LambdaMessageInterface2 m1 = () -> new Message();System.out.println( m1.getMessage());System.out.println("----------------------");//使用构造方法引用MessageInterface2 m2 = Message::new;System.out.println( m2.getMessage());//简化写法System.out.println("----------------------");System.out.println(((MessageInterface2) Message::new).getMessage());}
相关文章:
java基础之Java8新特性-方法引入
目录 1.简介 2.方法引入 方法引入遵循规范 方法引入种类 1.静态方法引入 2.对象方法引入 3.实例方法引入 4.构造函数引入 1.简介 方法引用是 Java 8 中引入的另一个重要特性,它提供了一种简洁的语法来直接引用现有方法或构造函数。方法引用可以看作是 Lambd…...
K8S中的hostPort、NodePort 、targetPort、port、containerPort 的区别
Dockerfile的EXPOSE Dockerfile中端口的声明: EXPOSE <端口1> [<端口2>...] 所以:EXPOSE的 第一个作用:只是说明docker容器开放了哪些端口,并没有将这些端口实际开放了出来!更多的作用是告诉运维人员或容器操作人员我开放了容器的哪些端口,只是一种说明。 …...
SpringBoot整合FreeMarker模板引擎
中文官方参考手册 http://freemarker.foofun.cn/ 1.先加入FreeMarker依赖 <dependency><groupId>org.freemarker</groupId><artifactId>freemarker</artifactId><version>2.3.23</version> </dependency>2.新建一个FreeMark…...
编程基础 - 变量与常量
编程基础 - 变量与常量 返回序言及专栏目录 文章目录 编程基础 - 变量与常量前言一、变量是什么?二、为什么要有变量三、局部变量和全局变量四、常量五、只读变量小结 前言 变量是编程最重要知识点之一,从根本上讲,编程就是对数据的操作&a…...
Linux入门攻坚——12、Linux网络属性配置相关知识2
CentOS 7网络属性配置: 传统命名机制:以太网eth[0,1,2,...],wlan[0,1,2...] 可预测功能的命名机制: udev支持多种不同的命名方案: Firmware ,拓扑结构 在对待设备文件这块,Linux改…...
如何自己实现一个分布式事务
实现分布式事务是一个复杂的过程,它需要精心设计并考虑数据的一致性、系统的可用性和分区容错能力。分布式事务确保在分布式系统中,即使是跨多个数据库、服务或消息队列,事务要么完全成功,要么完全失败。 以下是实现分布式事务的…...
使用Nonebot编写QQ机器人
使用 NoneBot 这个工具,来编写 QQ 机器人。 安装基础软件 一、安装 NoneBot 库 直接使用 pip 安装即可 pip install nonebot二、安装酷Q 软件和 HTTP API 插件 酷Q 软件可以直接到官网下载,https://cqp.cc/b/news,或者可以到网盘下载&am…...
认识SpringBoot中的条件注解
✅作者简介:大家好,我是Leo,热爱Java后端开发者,一个想要与大家共同进步的男人😉😉 🍎个人主页:Leo的博客 💞当前专栏: 循序渐进学SpringBoot ✨特色专栏&…...
使用PAI-DSW搭建基于LangChain的检索知识库问答机器人
教程简述 在本教程中,您将学习如何在阿里云交互式建模(PAI-DSW)中,基于LangChain的检索知识库实现知识问答。旨在建立一套对中文场景与开源模型支持友好、可离线运行的知识库问答解决方案。 LangChain是一个开源的框架,…...
优雅的通过Shell脚本生成Go的程序包
前言 随着Go语言的普及,越来越多的开发人员选择使用Go编写代码。虽然越来越多的公司项目已使用持续集成/持续部署(CI/CD)工具,用于自动化构建、测试和部署Go程序包,但存在一些部署在ECS服务器的Go程序包或需要手动编译…...
益生菌抗癌?补充这种益生菌,抑制肝癌,还改善肠道健康
撰文 | 宋文法 肠道菌群,是人体不可分割的组成部分,生活在我们肠道内的数万亿细菌对健康起着重要作用,它们影响着人的新陈代谢、消化能力、抵御感染、控制人体对药物的反应,甚至还能预防某些癌症。 非酒精性脂肪肝病,是…...
LLM漫谈(二)| QAnything支持任意格式文件或数据库的本地知识库问答系统
一、QAnything介绍 QAnything (Question and Answer based on Anything) 是致力于支持任意格式文件或数据库的本地知识库问答系统,可断网安装使用。 您的任何格式的本地文件都可以往里扔,即可获得准确、快速、靠谱的问答体验。 目前已支持格式: PDF&…...
Linux环境vscode clang-format格式化:vscode clang format command is not available亲测有效!
问题现象 vscode安装了clang-format插件,但是使用就报错 问题原因 设置中配置的clang-format插件工具路径不正确。 解决方案-亲测有效! 确认本地安装了clang-format工具:终端输入clang-format(也可能是clang-format-13等版本…...
Vue3前端 响应式数据 知识点
一、ref(基本类型数据,也可以定义对象类型的响应式数据。此时底层用的还是reactive) ref 创建基本类型的响应式数据 作用:定义响应式变量语法: let xxx ref(初始值)返回值: 一个 RefImp1 的实例对象,简称 ref对象或ref,ref 对象的 value 属…...
golang数据库连接池设置多少比较合适,如何设置?
设置数据库连接池的大小需要综合考虑应用程序的需求、数据库系统的性能、服务器资源等因素。连接池大小的不合理设置可能导致性能问题或资源浪费。 以下是一些建议: 考虑应用程序的并发需求: 连接池的大小应该足够满足应用程序的并发需求。如果你的应用…...
一、Mybatis 简介
本章概要 简介持久层框架对比快速入门(基于Mybatis3方式) 1.1 简介 https://mybatis.org/mybatis-3/zh/index.html MyBatis最初是Apache的一个开源项目iBatis, 2010年6月这个项目由Apache Software Foundation迁移到了Google Code。随着开发团队转投G…...
苹果Vision Pro将于1月27日上市!
在无数期待中,苹果全新产品Vision Pro头显终于定下上市日期。 彭博社记者马克古曼(Mark Gurman)于近日在X(前推特)平台爆料了这一信息,预计苹果Vision Pro头显将于2024年1月27日率先在美国上市。 在过去看…...
密码学(一)
文章目录 前言一、Cryptographic Primitives二、Cryptographic Keys2.1 Symmetric key cryptography2.2 asymmetric key cryptography 三、Confidentiality3.1 Symmetric key encryption algorithms3.2 asymmetric key block ciphers3.3 其他 四、Integrity4.1 secure hashing …...
VueRouter
1、用户权限问题 可以在路由全局前置守卫判断当前vuex里是否有token 有token值证明刚才登录过, 无token值证明未登录 router.beforeEach((to, from, next) > {const token store.state.tokenif (token) {// 如果有token, 证明已登录if (!store.state.userInfo.username) {/…...
什么是React.FC | 封装ant design弹框组件之:ant design 修改密码弹框组件
文章目录 一、什么是React.FC组件的 props 是什么意思二、封装ant design弹框组件之:ant design 修改密码弹框组件定义修改密码弹框组件使用修改密码弹框组件:[重要]关于提交时候,不同组件 表单数据共享报错:Button cannot be used as a JSX component.一、什么是React.FC …...
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以? 在 Golang 的面试中,map 类型的使用是一个常见的考点,其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...
VB.net复制Ntag213卡写入UID
本示例使用的发卡器:https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...
srs linux
下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935,SRS管理页面端口是8080,可…...
VTK如何让部分单位不可见
最近遇到一个需求,需要让一个vtkDataSet中的部分单元不可见,查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行,是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示,主要是最后一个参数,透明度…...
BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...
【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分
一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计,提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合:各模块职责清晰,便于独立开发…...
rnn判断string中第一次出现a的下标
# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...
Kafka入门-生产者
生产者 生产者发送流程: 延迟时间为0ms时,也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于:异步发送不需要等待结果,同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...
Scrapy-Redis分布式爬虫架构的可扩展性与容错性增强:基于微服务与容器化的解决方案
在大数据时代,海量数据的采集与处理成为企业和研究机构获取信息的关键环节。Scrapy-Redis作为一种经典的分布式爬虫架构,在处理大规模数据抓取任务时展现出强大的能力。然而,随着业务规模的不断扩大和数据抓取需求的日益复杂,传统…...
vue3 daterange正则踩坑
<el-form-item label"空置时间" prop"vacantTime"> <el-date-picker v-model"form.vacantTime" type"daterange" start-placeholder"开始日期" end-placeholder"结束日期" clearable :editable"fal…...
