springboot源码中this::selfInitialize怪异用法的含义解析

 更新时间:2023年03月31日 08:42:20   作者:kingtopest  
这篇文章主要介绍了springboot源码中this::selfInitialize怪异用法的含义解析,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

最近在看springboot源码中有一段很怪异的代码

  private ServletContextInitializer getSelfInitializer() {
        return this::selfInitialize;
    }

 按照通常的java 8 lambda理解: 双冒号无法就是方法调用的另一中写法,那么this::selfInitialize就是调用selfInitialize方法,但是这个方法不是返回void吗,为什么getSelfInitializer方法调用了这个方法还能返回ServletContextInitializer,从而继续执行onStartup方法呢?

是不是觉得非常奇怪,很难理解。 

于是,先简单断点调试一下,看一下getSelfInitializer方法返回值到底是什么:

从上面的getWebServer进来:

 可以看到initializers(也就是getSelfInitializer返回值,就是个数组)的元素类型是一个lambda表达式,它的入参类型是AnnotationConfigServletWebServerApplicationContext

AnnotationConfigServletWebServerApplicationContext的父类是ServletWebServerApplicationContext(也就是getSelfInitializer方法所在的类),其实也就是this

 那么可以推断this::selfInitialize相当于是整个被作为参数传递给了lambda表达式

为什么会有这种用法呢?

@FunctionalInterface
public interface ServletContextInitializer {
    void onStartup(ServletContext servletContext) throws ServletException;
}

可以看到ServletContextInitializer是一个函数式接口:

这里提两个重要的知识点

1. 函数式接口只能有一个方法。
2.  Lambda表达式就是一个函数式接口的实例,Lambda表达式也是函数式接口所定义方法的实现

所以,考虑到getSelfInitializer方法的返回值是ServletContextInitializer,那么this::selfInitialize这种lambda表达式的写法相当于下面的匿名内部类的代码:

new ServletContextInitializer() {
    @Override
    void onStartup(ServletContext servletContext) throws ServletException {
          selfInitialize(servletContext);
     };
}

this::selfInitialize是把selfInitialize方法作为整体作为参数传递给了lambda表达式,重写了ServletContextInitializer接口的onStartup方法的内部方法体。

所以,像this::${method}这种用法,通常是把method方法作为参数传递给lambda表达式达到重写函数式接口方法的目的,此时一定要看一下this::${method}所在方法的返回值类型,这个返回值类型就是函数式接口的类型。

总而言之: Lambda表达式的引入降低了代码的可读性,远没有匿名内部类(@override)那么清晰, java的函数式编程做的很烂,感觉就是一个生搬硬凑的破烂玩具,没有javascript做的好。

到此这篇关于springboot源码中this::selfInitialize怪异用法的含义的文章就介绍到这了,更多相关springboot this::selfInitialize用法内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 解决@Api注解不展示controller内容的问题

    解决@Api注解不展示controller内容的问题

    这篇文章主要介绍了解决@Api注解不展示controller内容的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教。
    2022-01-01
  • Java实现AES加密和解密方式完整示例

    Java实现AES加密和解密方式完整示例

    这篇文章主要给大家介绍了关于Java实现AES加密和解密方式的相关资料,AES加密为最常见的对称加密算法,是一种区块加密标准,这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用,需要的朋友可以参考下
    2023-10-10
  • Java聊天室之实现客户端群聊功能

    Java聊天室之实现客户端群聊功能

    这篇文章主要为大家详细介绍了Java简易聊天室之实现客户端群聊功能,文中的示例代码讲解详细,具有一定的借鉴价值,需要的可以了解一下
    2022-10-10
  • Java开发工具-scala处理json格式利器-json4s详解

    Java开发工具-scala处理json格式利器-json4s详解

    这篇文章主要介绍了开发工具-scala处理json格式利器-json4s,文章中处理方法讲解的很清楚,有需要的同学可以研究下
    2021-02-02
  • 关于maven项目引入maven库没有的jar处理办法

    关于maven项目引入maven库没有的jar处理办法

    这篇文章主要介绍了关于maven项目引入maven库没有的jar处理办法,在平时开发中,有些jar包是不存在maven中央库中的,那么此时该如何解决才能方便后续处理呢,需要的朋友可以参考下本文
    2023-03-03
  • java必学必会之equals方法

    java必学必会之equals方法

    java必学必会之equals方法,equals方法是 java.lang.Object 类的方法,想要了解更多关于equals方法的朋友,可以参考下文
    2015-12-12
  • Java多线程之多种锁和阻塞队列

    Java多线程之多种锁和阻塞队列

    今天带大家学习的是Java多线程的相关知识,文章围绕着java多种锁和阻塞队列展开,文中有非常详细的介绍,需要的朋友可以参考下
    2021-06-06
  • 浅谈Java8的特性之Optional类

    浅谈Java8的特性之Optional类

    这篇文章主要介绍了浅谈Java8的特性之Optional类,Optional类是 Java 8 引入的一个很有趣的特性,Optional 类是一个可以为null的容器对象,它主要解决的问题是臭名昭著的空指针异常,需要的朋友可以参考下
    2023-08-08
  • java实现时间控制的几种方案

    java实现时间控制的几种方案

    这篇文章主要介绍了java实现时间控制的几种方案,本文从多个方面给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-07-07
  • 在Spring boot的项目中使用Junit进行单体测试

    在Spring boot的项目中使用Junit进行单体测试

    今天小编就为大家分享一篇关于spring boot使用Junit进行测试,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2018-12-12

最新评论