使用默认方法的界面演变–第一部分:方法

几周前,我们详细研究了默认方法 -Java 8中引入的一项功能,该功能允许为接口方法提供实现,即方法主体,从而定义接口中的行为。 引入此功能是为了实现接口演进 。

在JDK的上下文中,这意味着在不破坏所有代码的情况下向接口添加新方法。 但是,尽管Java本身非常致力于保持向后兼容性,但其他项目并不一定要做到这一点。 如果他们愿意,他们可以以让客户更改代码为代价来开发接口。

在Java 8之前,这经常涉及客户端编译错误,因此可以避免更改,否则客户端必须一次性迁移。 使用默认方法,接口演变可以成为一个无错误的过程,在此过程中,客户端可以在版本之间留出时间来逐步更新代码。 这大大增加了开发接口的可行性,并使其成为常规的库开发工具。

让我们看一下如何添加,替换和删除接口方法。 未来的文章将探讨替换整个接口的方法。

总览

该帖子首先定义了一些术语,然后介绍了添加,替换和删除接口方法的方法。 它是从更改库中界面的开发人员的角度编写的。

我觉得该主题不需要示例,因此我没有编写任何示例。 如果您不同意并希望看到一些内容,请发表评论,并且-在时间允许的情况下-我会写一些。

术语

接口具有实现调用者 。 两者都可以存在于库中,在这种情况下,它们都称为internal ,或者在客户端代码中称为external 。 这总共增加了四种使用界面的类别。

根据界面的发展方式和存在的用途,必须采用不同的模式。 当然,如果既不存在外部实现也不存在外部调用者,则这些都不是必需的,因此本文的其余部分假定这些情况中至少有一种确实存在。

接口演变–方法

因此,让我们看看如何在不破坏客户端代码的情况下添加,替换或删除接口方法。

通常可以通过执行以下过程来实现:

新版本

该库的新版本已发布,其中界面定义是过渡性的,并结合了旧的和新的所需轮廓。 默认方法可确保所有外部实现和调用仍然有效,并且在更新时不会出现编译错误。

过渡

然后,客户就有时间从旧大纲过渡到新大纲。 同样,默认方法可确保适应的外部实现和调用有效,并且可以进行更改而不会编译错误。

新版本

在新版本中,该库删除了旧轮廓的残差。 鉴于客户端明智地利用了自己的时间并进行了必要的更改,因此发布新版本不会导致编译错误。

这个过程使客户能够按自己的时间表平稳地更新代码,这使得接口的发展比以前更加可行。

由Johanna Pung在CC-BY-SA 3.0下为Wikimedia Deutschland发布。

Johanna Pung在CC-BY-SA 3.0下为Wikimedia Deutschland 发布 。

遵循以下详细步骤时,请确保检查何时更新了内部和外部实现以及何时允许内部和外部调用者使用所涉及的方法。 确保在您自己的代码中遵循此过程,并为您的客户正确记录下来,以便他们知道何时执行操作。 Javadoc标签@Deprecated@apiNote是实现此目的的好方法。

通常,不必按该顺序执行过渡内的步骤。 如果是,则明确指出。

如果您向客户提供可以在其界面实现上运行的测试,则这些步骤中包含测试。

仅当存在外部接口实现时才需要此过程。 由于该方法是新方法,因此当然尚未调用,因此可以忽略这种情况。 区分是否可以提供合理的默认实现是有意义的。

存在合理的默认实现

新版本
  • 为新方法定义测试
  • 使用默认实现(通过测试)添加方法
  • 内部呼叫者可以使用该方法
  • 内部实现可以在必要时覆盖该方法
过渡
  • 外部呼叫者可以使用该方法
  • 外部实现可以在必要时覆盖该方法

无需执行任何操作,也不需要任何新版本。 这就是Java 8中添加的许多新的默认方法所发生的事情。

不存在合理的默认实现

新版本
  • 定义新方法的测试; 这些必须接受UnupportedOperationExceptions
  • 添加方法:
    • 包括一个引发UnupportedOperationException的默认实现(通过测试)
    • @apiNote注释文档,默认实现将最终被删除
  • 在所有内部实现中覆盖该方法
过渡

必须按该顺序执行以下步骤:

  • 外部实现必须重写该方法
  • 外部呼叫者可以使用该方法
新版本
  • 测试不再接受UnupportedOperationExceptions
  • 使方法抽象:
    • 删除默认实现
    • 删除@apiNote注释
  • 内部呼叫者可以使用该方法

勉强一致的默认实现允许外部实现逐渐更新。 请注意,在实际在内部或外部调用新方法之前,将更新所有实现。 因此,永远不会发生UnupportedOperationException。

更换

在这种情况下,一种方法将被另一种方法替代。 这包括方法更改其签名(例如,其名称或参数数量)的情况,在这种情况下,新版本可以看作是替换旧版本。

当存在外部实现或外部调用者时,必须应用此模式。 仅在两种方法在功能上等效时才起作用。 否则,就是添加一个功能并删除另一个功能的情况。

新版本
  • 为新方法定义测试
  • 添加新方法:
    • 包括调用旧方法的默认实现
    • @apiNote注释文档,默认实现将最终被删除
  • 弃用旧方法:
    • 包括调用新方法的默认实现(旨在进行循环调用;如果存在默认实现,则可以保留)
    • @apiNote注释文档,默认实现将最终被删除
    • @Deprecation评论文档说明将使用新方法
  • 内部实现会覆盖新方法,而不是旧方法
  • 内部调用者使用新方法代替旧方法
过渡
  • 外部实现会覆盖新方法,而不是旧方法
  • 外部呼叫者使用新方法代替旧方法
新版本
  • 使新方法抽象:
    • 删除默认实现
    • 删除@apiNote注释
  • 删除旧方法

尽管循环调用看起来很有趣,但它们确保实现哪种方法都无关紧要。 但是,由于这两种变体都有默认实现,因此,如果两种实现均未实现,则编译器不会产生错误。 不幸的是,这会产生无限循环,因此请确保将其指出给客户。 如果您为他们的实现提供测试,或者他们编写了自己的实现,则他们会立即意识到这一点。

去掉

删除方法时,根据是否存在外部实现,可以应用不同的模式。

存在外部实现

新版本
  • 方法的测试必须接受UnupportedOperationExceptions
  • 弃用该方法:
    • 包括一个引发UnupportedOperationException的默认实现(通过更新的测试)
    • @Deprecation注释文档表明该方法最终将被删除
    • @apiNote注释文档说明默认实现仅存在于逐步淘汰方法中
  • 内部呼叫者停止使用该方法
过渡

必须按该顺序执行以下步骤:

  • 外部呼叫者停止使用该方法
  • 该方法的外部实现已删除
新版本
  • 删除方法

请注意,只有在不存在对该方法的更多调用之后,才删除内部和外部实现。 因此,永远不会发生UnupportedOperationException。

外部实现不存在

在这种情况下,定期弃用就足够了。 仅出于完整性考虑而列出了这种情况。

新版本
  • @Depreated弃用该方法
  • 内部呼叫者停止使用该方法
过渡
  • 外部呼叫者停止呼叫方法
新版本
  • 删除方法

反射

我们已经看到了如何通过添加,替换和删除方法来实现界面演化:新的界面版本结合了旧轮廓和新轮廓,客户端从前者过渡到后者,而最终版本则消除了旧轮廓的残留。 所涉及方法的默认实现确保客户端代码的旧版本和新版本都能正确编译和运行。

翻译自: https://www.javacodegeeks.com/2015/03/interface-evolution-with-default-methods-part-i-methods.html

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

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

相关文章

java左手握右手_环保型燃料—丙烷(C3H8)曾用于北京奥运会“祥云”火炬燃料,下列有关烷烃的说法不正确的是()A.丙烷分子中三个...

参考答案如下环保会祥【单选题】环境景观设计的核心就是以研究()为基础。型燃下列【判断题】构成中央处理器的两大部件是运算器和存储器。料丙料【单选题】通过下列哪种方式可以获得最强的免疫效果【单选题】根据断面图的标注形式,烷C烷烃下列绘制规范的断面图是【单…

windbg script ---- 禁用IsDebuggerPresent

简单的script r $t0 kernelBase!IsDebuggerPresent; eb $t00x9 31 c0 90 90强制把原代码改成xor eax, eax; nop; nop 注意在xp下,使用kernel32 转载于:https://www.cnblogs.com/hgy413/p/3693400.html

java两个和三个_Java语言基础(day_03)

数据类型中补充的几个小问题1)在定义Long或者Float类型变量的时候,要加L或者f。整数默认是int类型,浮点数默认晨double。byte,short在定义的肘候,他们接收的某实是一个int类型的值。这个是自己做了一个数据检测的,如果…

Hibernate中的JPA 2.1条件删除/更新和临时表

从JPA 2.0版开始, EntityManager提供了方法getCriteriaBuilder()来动态构建选择查询,而无需使用Java持久性查询语言(JPQL)进行字符串连接。 在2.1版中,此CriteriaBuilder提供了两个新方法createCriteriaDelete()和crea…

使用Hamcrest增强JUnit的测试能力

package com.jadyer.service;import java.util.HashMap; import java.util.Map;import org.hamcrest.Matchers; import org.junit.Assert; import org.junit.Test;/*** 使用Hamcrest增强JUnit的测试能力* see Hamcrest框架提供了一些相对通俗并高效的方法来进行一些junit比较困…

在Websphere 8.0上安装Liferay 6.2 Enterprise Edition

为Liferay准备Websphere 当应用服务器二进制文件均已安装完毕,启动WebSphere应用服务器(WAS) 配置文件管理工具来创建一个配置文件适用于Liferay的和遵循的指示说明这里正式Liferay的文档。 这些说明用于在Websphere 8.5上安装Liferay 6.2&am…

java完数流程图_编程基本功训练:流程图画法及练习

对于“程序设计”的工作,许多初学者的理解就是“写代码”。同样,新手们苦恼的问题是,他们只会“写代码”。当接到一个新的任务,不少人总是在第一时间就爬到键盘上去敲代码。敲着敲着,就把自己绕糊涂了。头晕脑胀地坚持…

iOS modal view的关闭和显示问题

今天遇到一个问题: 需要关闭当前modal view,再present另一个modal view。 如果这么写: [self dismissModalViewControllerAnimated:NO];[self.delegate showBorderDetectionView];执行了第一句,再执行第二句的时候,sel…

西工大java高级网络编程_奥鹏西工大16春《JAVA高级网络编程》平时作业

西工大16春《JV高级网络编程》平时作业一、单选题(共 25 道试题,共 100 分。)1. 假设以tomt为w服务器,在hllopp应用中有一个hllo.jsp,它的文件路径如下: %TOMT_HOM%/wpps/hllopp/hllo/hllo.jsp 那么在浏览器端访问hllo.jsp的URL是()。. http:…

c#导出Excel

问题:用户查询一些数据,需要对页面上的数据生成excel文件。 分析:写文件,用excel进程,或者使用response方法(都是通过网上查资料,个人就理解成这两个) 使用excel进程有一个确定&…

使用Java 8流遍历递归数据结构

Streams API是Java 8中的真正瑰宝,我一直在为它们寻找或多或少的意外用途。 我最近写过有关将它们用作ForkJoinPool门面的文章 。 这是另一个有趣的例子:遍历递归数据结构。 事不宜迟,请看一下代码: class Tree {private int va…

mysql把用户权限授予新用户_MySQL新建普通用户和库并授予新用户对新库的所有权限...

新建库新建cmf和amon两个库,并指定默认字符集mysql> create database cmf DEFAULT CHARACTER SET utf8;Query OK, 1 row affected (0.00 sec)mysql> create database amon DEFAULT CHARACTER SET utf8;Query OK, 1 row affected (0.00 sec)新建用户新建cmf和a…

快速入门:OpenShift上的Spring Boot和WildfFly 8.2

与Spring Boot,WildFly和OpenShift相比,这是真正的“快速入门”,与我上一篇更具描述性的文章相反。 先决条件 在开始构建应用程序之前,我们需要安装一个OpenShift免费帐户和客户端工具。 步骤1:建立WildFly应用程式 …

java开发环境搭建 pdf_01搭建java web开发环境.pdf

01搭建java web开发环境.pdf还剩19页未读,继续阅读下载文档到电脑,马上远离加班熬夜!亲,很抱歉,此页已超出免费预览范围啦!如果喜欢就下载吧,价低环保!内容要点:( 7)在 M…

linux培训笔记1

第五章 文件和目录的管理 linux命令的基本格式 #命令 [选项] [参数] 1、linux下的常用命令 (1)ls 查看(列出)目录下的内容 -l 查看文件详细信息 drwxr-xr-x. 23 root root 4096 5月 31 15:06 var 文件类型和…

Java 8 Optional不仅用于替换空值

总览 在Java 8中,您可以返回Optional而不是返回null。 就像您在Java 7中所做的那样。这取决于您是否倾向于忘记检查null还是使用静态代码分析检查对nullalbe的引用,这可能有很大的不同。 但是,还有一种更引人注目的情况是将Optional视为具有…

WCF学习笔记之序列化

DataContractAttribute 与 DataMenberAttribute DataContractAttribute该特性只能用于枚举、类和结构体,而不能用于接口;又因为DataContractAttribute是不可以被继承的,所以要所有作为数据契约的类型自身必须有这么一个特性;而且一…

转载[POJ题型分类]

北大ACM题分类 主流算法: 1.搜索 //回溯 2.DP(动态规划)  3.贪心  4.图论 //Dijkstra、最小生成树、网络流 5.数论 //解模线性方程 6.计算几何 //凸壳、同等安置矩形的并的面积与周长 7.组合数学 //Polya定理 8.模拟  9.数据结构 //…

在AWS Elastic MapReduce上运行PageRank Hadoop作业

在上一篇文章中,我描述了执行PageRank计算的示例,该示例是使用Apache Hadoop进行Mining Massive Dataset课程的一部分。 在那篇文章中,我接受了Java中现有的Hadoop作业,并做了一些修改(添加了单元测试,并通…

java sort 第二个参数_详解java Collections.sort的两种用法

Collections是一个工具类,sort是其中的静态方法,是用来对List类型进行排序的,它有两种参数形式:public static > void sort(List list) {list.sort(null);}public static void sort(List list, Comparator super T> c) {lis…