java nio的演进_Java接口的防御性API演进

java nio的演进

API的发展绝对是不平凡的。 只有少数几个需要处理的事情。 我们大多数人每天都在使用内部专有API。 现代IDE附带了很棒的工具,可以分解,重命名,上拉,下推,间接,委托,推断,泛化我们的代码伪像。 这些工具使重构我们的内部API变得轻而易举。 但是我们中的一些人在公共API上工作,其中规则发生了巨大变化。 如果正确完成,则对公共API进行版本控制。 每次更改(兼容或不兼容)都应在新的API版本中发布。 多数人会同意,API演化应在主要和次要版本中完成,类​​似于语义版本控制中指定的内容 。 简而言之:不兼容的API更改发布在主要版本(1.0、2.0、3.0)中,而兼容的API更改/增强发布在次要版本(1.0、1.1、1.2)中。

如果您正在计划,那么您将在很长时间内预见到大多数不兼容的更改,然后才实际发布下一个主要版本。 弃用是Java中提早宣布这样的变化的一个好工具。

接口API的演变

现在,弃用是一个很好的工具,它表明您将要从API中删除类型或成员。 如果要在接口的类型层次结构中添加方法或类型怎么办? 这意味着实现您的接口的所有客户端代码都将中断–至少只要尚未引入Java 8的防御方法即可。 有几种技术可以规避/解决此问题:

1.不在乎

是的,这也是一种选择。 您的API是公开的,但使用的可能不是很多。 让我们面对现实:并不是我们所有人都在JDK / Eclipse / Apache / etc等代码库上工作。 如果您很友好,则至少要等待主要版本引入新方法。 但是,如果确实需要,您可以打破语义版本控制的规则-如果您可以处理引起一群愤怒的用户的后果。

但是请注意,其他平台并不像Java Universe那样向后兼容(通常是根据语言设计或语言复杂性)。 例如,使用Scala将事物声明为隐式的各种方法,您的API并不总是完美的。

2.用Java方式完成

“ Java”方式根本不发展接口。 JDK中的大多数API类型永远都是今天的样子。 当然,这使API感觉很“恐龙化”,并在各种相似类型之间(例如StringBuffer和StringBuilder或Hashtable和HashMap)增加了很多冗余。

请注意,Java的某些部分不遵循“ Java”方式。 最具体地说,JDBC API就是这种情况,它是根据第1节“不关心它”的规则演变的。

3.用Eclipse的方式来做

Eclipse的内部包含大量API。 在Eclipse中/进行开发时, 有很多指南如何开发自己的API(即,插件的公共部分)。 关于Eclipse家伙如何扩展接口的一个示例是IAnnotationHover类型。 根据Javadoc合同,它允许实现还实现IAnnotationHoverExtension和IAnnotationHoverExtension2 。 显然,从长远来看,这种经过改进的API很难维护,测试和记录文档,最终很难使用! (考虑ICompletionProposal及其6(!)扩展类型)

4.等待Java 8

在Java 8中,您将能够使用防御者方法 。 这意味着您可以为新的接口方法提供明智的默认实现 ,如Java 1.8的java.util.Iterator (摘录)所示:

public interface Iterator<E> {// These methods are kept the same:boolean hasNext();E next();// This method is now made 'optional' (finally!)public default void remove() {throw new UnsupportedOperationException('remove');}// This method has been added compatibly in Java 1.8default void forEach(Consumer<? super E> consumer) {Objects.requireNonNull(consumer);while (hasNext())consumer.accept(next());}
}

当然,您并不总是希望提供默认的实现。 通常,您的接口是必须完全由客户端代码实现的合同。

5.提供公共默认实现

在许多情况下,明智的做法是告诉客户端代码,他们可能需要自己承担风险(由于API的演变)来实现接口,而他们应该更好地扩展提供的抽象或默认实现。 一个很好的例子是java.util.List ,可能很难正确实现。 对于简单的而不是对性能至关重要的自定义列表,大多数用户可能选择扩展java.util.AbstractList 。 然后剩下剩下要实现的唯一方法是get(int)和size()。所有其他方法的行为都可以从这两个方法中得出:

class EmptyList<E> extends AbstractList<E> {@Overridepublic E get(int index) {throw new IndexOutOfBoundsException('No elements here');}@Overridepublic int size() {return 0;}
}

遵循的一个很好的约定是,如果您的默认实现为AbstractXXX,则将其命名为默认实现;如果是具体的,则将其命名为DefaultXXX

6.使您的API很难实现

现在,这并不是真正的好技术,而只是一个可能的事实。 如果您的API很难实现(一个接口中有100多个方法),则用户可能不会这样做。 注意: 可能 。 永远不要低估疯狂的用户。 一个示例是jOOQ的 org.jooq.Field类型,它表示数据库字段/列。 实际上,这种类型是jOOQ的内部领域特定语言的一部分 ,提供了可以在数据库列上执行的各种操作和功能。 当然,拥有太多方法是一个例外,并且-如果您不设计DSL-可能表明整体设计不佳。

7.添加编译器和IDE技巧

最后但并非最不重要的一点是,您可以将一些巧妙的技巧应用于您的API,以帮助人们了解他们应该做些什么,以便正确实现基于接口的API。 这是一个艰难的例子,它使API设计人员的意图直接扑向您的脸。 考虑一下org.hamcrest.Matcher API的以下摘录:

public interface Matcher<T> extends SelfDescribing {// This is what a Matcher really does.boolean matches(Object item);void describeMismatch(Object item, Description mismatchDescription);// Now check out this method here:/*** This method simply acts a friendly reminder not to implement * Matcher directly and instead extend BaseMatcher. It's easy to * ignore JavaDoc, but a bit harder to ignore compile errors .** @see Matcher for reasons why.* @see BaseMatcher* @deprecated to make*/@Deprecatedvoid _dont_implement_Matcher___instead_extend_BaseMatcher_();
}

“友好的提醒” ,来吧。

其他方法

我敢肯定,还有许多其他方法可以开发基于接口的API。 我很好奇您的想法!

参考: JAVA,SQL和JOOQ博客上的JCG合作伙伴 Lukas Eder 提供了Java接口的防御性API演变 。

翻译自: https://www.javacodegeeks.com/2013/02/defensive-api-evolution-with-java-interfaces.html

java nio的演进

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

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

相关文章

python层次聚类法画图_Python实现简单层次聚类算法以及可视化

本文实例为大家分享了Python实现简单层次聚类算法&#xff0c;以及可视化&#xff0c;供大家参考&#xff0c;具体内容如下基本的算法思路就是&#xff1a;把当前组间距离最小的两组合并成一组。算法的差异在算法如何确定组件的距离&#xff0c;一般有最大距离&#xff0c;最小…

range函数python2和3区别_【后端开发】range函数python2和3区别

range函数是一个用来创建算数级数序列的通用函数&#xff0c;返回一个[start, start step, start 2 * step, ...]结构的整数序列&#xff1b;py2中的range()函数用法&#xff1a;&#xff08;推荐学习&#xff1a;Python视频教程&#xff09; range()返回的是一个列表 >&g…

mysql AUTO_INC 是否锁_AUTO-INC锁的一些思考

AUTO-INC锁是一个表级锁&#xff0c;这种锁是作用于语句的而不是事务(即语句执行完了锁就会被释放)。innodb_autoinc_lock_mode用于控制AUTO-INC的锁表逻辑&#xff0c;可能的取值为0,1,2.innodb_autoinc_lock_mode0 (每次都会产生表锁)不管是对于simple inserts(insert into v…

Java 8可选

在编程时&#xff0c;我们都面临着最&#xff08; 臭名昭著 &#xff09;的NullPointerException 。 而且我相信我们所有人都同意&#xff0c;遇到NullPointerException也是一种痛苦。 为了使读者了解最新情况&#xff0c;著名的计算机科学家Tony Hoare引入了空引用&#xff0c…

matlab cat函数_如何用Matlab编写贪吃蛇游戏?(持续更新)

今后我们实验室的研究重点将会聚焦在“基于游戏的测评”和”教育游戏化“这两个主题上&#xff0c;因此很有必要研究实现“爆款”游戏的一些基本的技术方法。这篇文章将介绍如何借助Matlab GUI 面向对象编程技术实现贪吃蛇游戏。所有的游戏都可以解构成至少两个层次&#xff1…

python程序设计案例课堂第二篇_Python程序设计案例课堂第二篇核心技术第十章图形用户界面...

第10章 图形用户界面保存并运行程序&#xff0c;结果如图10-1所示。C:\Users\Administrator>python d:\python\ch10\10.1.py图10-1 程序运行结果【案例剖析】上述代码的含义分析如下。(1) 第1行&#xff1a;加载tkinter 模块。(2) 第 2 行&#xff1a;使用tkinter 模块的Tk(…

fprintf函数的用法matlab_极力推荐这个Matlab教程

点击蓝字 关注我们儿童节快乐前些日子, 由于一些原因的需要, 又把曾经的毕业论文拿来, 改吧改吧, 发现有些地方真的惨目忍睹, 只怪当时太年轻, 没想到给自己挖了一个大坑, 不,, 应该称之为巨坑, 对于论文中涉及到的代码, 当时主要使用了伪代码的形式, 以及现学现用的Python, 可…

websockets_使用Java WebSockets,JSR 356和JSON映射到POJO的

websockets因此&#xff0c;我一直在研究Tyrus &#xff08;JSR 356 WebSocket for Java规范的参考实现&#xff09;。 因为我一直在寻找测试工具&#xff0c;所以我对在Java中同时运行客户端和服务器端感兴趣。 因此&#xff0c;恐怕此博客文章中没有HTML5。 在此示例中&…

查看mysql主从复制是否成功的命令_mysql主从复制 - hong查理的个人空间 - OSCHINA - 中文开源技术交流社区...

1.配置 my.cof服务器A(192.168.1.2)配置如下log-bin mysql-binserver-id 1expire-logs-days 7#日志设置最高7天replicate-do-db test #需要同步的binlog-ignore-db mysql #忽略同步的binlog-ignore-db information_schema #忽略同步的auto-increment-increment 2…

python抓取数据时失败_爬取数据缺失的补坑,Python数据爬取的坑坑洼洼如何铲平...

渣渣业余选手讲解&#xff0c;关于爬取数据缺失的补坑&#xff0c;一点点关于Python数据爬取的坑坑洼洼如何铲平&#xff0c;个人的一些心得体会&#xff0c;还有结合实例的数据缺失的补全&#xff0c;几点参考&#xff0c;仅供观赏&#xff0c;如有雷同&#xff0c;那肯定是我…

关于总决赛

可以将变量声明为final。 最终变量只能分配一次。 如果分配了最终变量&#xff0c;则将导致编译时错误&#xff0c;除非在分配前立即将其绝对取消分配。 分配任何最终变量后&#xff0c;将永远无法对其进行更改。 如果变量引用任何对象的任何实例&#xff0c;它将继续引用相同的…

java中void_关于java中void的用法?

阿波罗的战车void除了说明该方法没有返回值外&#xff0c;还有什么作用呢&#xff1f;构造方法同样也是没有返回值的&#xff0c;那它和void方法有什么区别呢&#xff1f;构造方法与方法又有什么区别&#xff1f;用具象的实物来表现的话三者有何种关系呢&#xff1f;id 除了说明…

卷积神经网络mnist手写数字识别代码_搭建经典LeNet5 CNN卷积神经网络对Mnist手写数字数据识别实例与注释讲解,准确率达到97%...

LeNet-5卷积神经网络是最经典的卷积网络之一&#xff0c;这篇文章就在LeNet-5的基础上加入了一些tensorflow的有趣函数&#xff0c;对LeNet-5做了改动&#xff0c;也是对一些tf函数的实例化笔记吧。环境 Pycharm2019Python3.7.6tensorflow 2.0 话不多说&#xff0c;先放完整源码…

glassfish_多种监视和管理GlassFish 3的方法

glassfishGlassFish 3支持多种监视和管理方法。 在本文中&#xff0c;我将简要介绍GlassFish提供的管理&#xff0c;监视和管理方法。 GlassFish管理控制台 GlassFish基于Web的管理控制台GUI可能是GlassFish管理最著名的界面。 默认情况下&#xff0c;运行GlassFish后&#xf…

java 阻塞锁_Java实现锁、公平锁、读写锁、信号量、阻塞队列、线程池等常用并发工具...

锁的实现锁的实现其实很简单&#xff0c;主要使用Java中synchronized关键字。public class Lock {private volatile boolean isLocked false;private Thread lockingThread null;public synchronized void lock() throws InterruptedExpection {while(isLocked){wait();}isLo…

flask-mail异步发送邮件_SpringBoot 2.0 集成 JavaMail ,实现异步发送邮件

一、JavaMail的核心API1、API功能图解2、API说明(1)、Message 类:javax.mail.Message 类是创建和解析邮件的一个抽象类子类javax.mail.internet.MimeMessage &#xff1a;表示一份电子邮件。 发送邮件时&#xff0c;首先创建出封装了邮件数据的 Message 对象&#xff0c; 然后把…

Java 9中什么是私有的?

在进行面试时&#xff0c;我发现大多数应聘者都不知道Java中的private修饰符真正意味着什么。 他们知道一些足以进行日常编码的事情&#xff0c;但还远远不够。 这不成问题。 足够了解就足够了。 但是&#xff0c;了解Java的一些内部工作仍然很有趣。 在极少数情况下&#xff0…

python国际象棋ai程序_用Python编写一个国际象棋AI程序

最近我用Python做了一个国际象棋程序并把代码发布在Github上了。这个代码不到1000行&#xff0c;大概20%用来实现AI。在这篇文章中我会介绍这个AI如何工作&#xff0c;每一个部分做什么&#xff0c;它为什么能那样工作起来。你可以直接通读本文&#xff0c;或者去下载代码&…

java switch case怎么判断范围_【转】Java期末复习攻略!

期末19年就这样要过去了&#xff0c;终于到了小时候作文里的未来呢&#xff01;然而&#xff0c;期末考试也随之来临了。不知大家“预习”的怎么样呢&#xff1f; 期末复习资料的放送快接近尾声了下面康康学长学姐们怎么教你们打java这个boss(下面是java大佬给大家的复习建议以…

java list 去重复元素_java List去掉重复元素的几种方式

使用LinkedHashSet删除arraylist中的重复数据(有序)List words Arrays.asList("a","b","b","c","c","d");HashSet setnew LinkedHashSet<>(words);for(String word:set){System.out.println(word);}使用Has…