当前位置: 首页 > news >正文

夜间正能量网站入口网址不用下载网站seo服务公司

夜间正能量网站入口网址不用下载,网站seo服务公司,wordpress 过滤html,做游戏网站多少钱Java8实战-总结37 默认方法不断演进的 API初始版本的 API第二版 API 默认方法 传统上,Java程序的接口是将相关方法按照约定组合到一起的方式。实现接口的类必须为接口中定义的每个方法提供一个实现,或者从父类中继承它的实现。但是,一旦类库…

Java8实战-总结37

  • 默认方法
    • 不断演进的 API
      • 初始版本的 API
      • 第二版 API

默认方法

传统上,Java程序的接口是将相关方法按照约定组合到一起的方式。实现接口的类必须为接口中定义的每个方法提供一个实现,或者从父类中继承它的实现。但是,一旦类库的设计者需要更新接口,向其中加入新的方法,这种方式就会出现问题。

现实情况是,现存的实体类往往不在接口设计者的控制范围之内,这些实体类为了适配新的接口约定也需要进行修改。由于Java 8API在现存的接口上引入了非常多的新方法,这种变化带来的问题也愈加严重,一个例子就是前面使用过的List接口上的sort方法。像GuavaApache Commons这样的框架现在都需要修改实现了List接口的所有类,为其添加sort方法的实现。

Java 8为了解决这一问题引入了一种新的机制。Java 8中的接口现在支持在声明方法的同时提供实现,通过两种方式可以完成这种操作。其一,Java 8允许在接口内声明静态方法。其二,Java 8引入了一个新功能,叫默认方法,通过默认方法可以指定接口方法的默认实现。换句话说,接口能提供方法的具体实现。因此,实现接口的类如果不显式地提供该方法的具体实现,就会自动继承默认的实现。这种机制可以使你平滑地进行接口的优化和演进。实际上,到目前为止已经使用了多个默认方法。两个例子就是你前面已经见过的List接口中的sort,以及Collection接口中的stream

List接口中的sort方法是Java 8中全新的方法,它的定义如下:

default void sort(Comparator<? super E> c) { Collections.sort(this, c); 
} 

注意返回类型之前的新default修饰符。通过default修饰符,能够知道一个方法是否为默认方法。这里sort方法调用了Collections.sort方法进行排序操作。由于有了这个新的方法,现在可以直接通过调用sort,对列表中的元素进行排序。

List<Integer> numbers = Arrays.asList(3, 5, 1, 2, 6); 
numbers.sort(Comparator.naturalOrder()); 

不过除此之外,这段代码中还有些其他的新东西,Comparator.naturalOrder方法。这是Comparator接口的一个全新的静态方法,它返回一个Comparator对象,并按自然序列对其中的元素进行排序(即标准的字母数字方式排序)。

Collection中的stream方法的定义如下:

default Stream<E> stream() { return StreamSupport.stream(spliterator(), false); 
} 

这里stream 方法中调用了SteamSupport.stream方法来返回一个流。

为什么要在乎默认方法?默认方法的主要目标用户是类库的设计者,默认方法的引入就是为了以兼容的方式解决像Java API这样的类库的演进问题的,如下图所示:
在这里插入图片描述
简而言之,向接口添加方法是诸多问题的罪恶之源;一旦接口发生变化,实现这些接口的类往往也需要更新,提供新添方法的实现才能适配接口的变化。如果对接口以及它所有相关的实现有完全的控制,这可能不是个大问题。但是这种情况是极少的。这就是引入默认方法的目的:它让类可以自动地继承接口的一个默认实现。

默认方法为接口的演进提供了一种平滑的方式,你的改动将不会导致已有代码的修改。此外,默认方法为方法的多继承提供了一种更灵活的机制,可以更好地规划代码结构:Java 8类可以从多个接口继承默认方法。

静态方法及接口
同时定义接口以及工具辅助类(companion class)是Java语言常用的一种模式,工具类定
义了与接口实例协作的很多静态方法。比如,Collections就是处理Collection对象的辅
助类。由于静态方法可以存在于接口内部,你代码中的这些辅助类就没有了存在的必要,你可
以把这些静态方法转移到接口内部。为了保持后向的兼容性,这些类依然会存在于Java应用程
序的接口之中。

不断演进的 API

假设你是一个流行Java绘图库的设计者。库中包含了一个Resizable接口,它定义了一个简单的可缩放形状必须支持的很多方法, 比如:setHeight、setWidth、getHeight、getWidth以及setAbsoluteSize。此外,还提供了几个额外的实现(out-of-box implementation),如正方形、长方形。由于这个库非常流行,一些用户使用Resizable接口创建了他们自己感兴趣的实现,比如椭圆。

发布API几个月之后,你突然意识到Resizable接口遗漏了一些功能。比如,如果接口提供一个setRelativeSize方法,可以接受参数实现对形状的大小进行调整,那么接口的易用性会更好。这看起来很容易:为Resizable接口添加setRelativeSize方法,再更新SquareRectangle的实现就好了。不过,事情并非如此简单,要考虑已经使用了你接口的用户,他们已经按照自身的需求实现了Resizable接口,他们该如何应对这样的变更呢?非常不幸,你无法访问,也无法改动他们实现了Resizable接口的类。这也是Java库的设计者需要改进Java API时面对的问题。以一个具体的实例为例,深入探讨修改一个已发布接口的种种后果。

初始版本的 API

Resizable接口的最初版本提供了下面这些方法:

public interface Resizable extends Drawable { int getWidth(); int getHeight(); void setWidth(int width); void setHeight(int height); void setAbsoluteSize(int width, int height); 
} 

用户实现
一位用户根据自身的需求实现了Resizable接口,创建了Ellipse类:

public class Ellipse implements Resizable {} 

他实现了一个处理各种Resizable形状(包括Ellipse)的游戏:

public class Game { public static void main(String...args) { List<Resizable> resizableShapes = Arrays.asList(new Square(), new Rectangle(), new Ellipse()); Utils.paint(resizableShapes); } 
}public class Utils { public static void paint(List<Resizable> l) { l.forEach(r -> { r.setAbsoluteSize(42, 42); r.draw(); }); } 
} 

第二版 API

库上线使用几个月之后,你收到很多请求,要求你更新Resizable的实现,让Square、Rectangle以及其他的形状都能支持setRelativeSize方法。为了满足这些新的需求,你发布了第二版API,具体如下图所示:

public interface Resizable { int getWidth(); int getHeight(); void setWidth(int width);void setHeight(int height); void setAbsoluteSize(int width, int height); void setRelativeSize(int wFactor, int hFactor);
}

在这里插入图片描述
用户面临的窘境
Resizable接口的更新导致了一系列的问题。首先,接口现在要求它所有的实现类添加setRelativeSize方法的实现。但是用户最初实现的Ellipse类并未包含setRelativeSize方法。向接口添加新方法是二进制兼容的,这意味着如果不重新编译该类,即使不实现新的方法,现有类的实现依旧可以运行。不过,用户可能修改他的游戏,在他的Utils.paint方法中调用setRelativeSize方法,因为paint方法接受一个Resizable对象列表作为参数。如果传递的是一个Ellipse对象,程序就会抛出一个运行时错误,因为它并未实现setRelativeSize方法:

Exception in thread "main" java.lang.AbstractMethodError: lambdasinaction.chap9.Ellipse.setRelativeSize(II)V 

其次,如果用户试图重新编译整个应用(包括Ellipse类),他会遭遇下面的编译错误:

lambdasinaction/chap9/Ellipse.java:6: error: Ellipse is not abstract and does not override abstract method setRelativeSize(int,int) in Resizable 

最后,更新已发布API会导致后向兼容性问题。这就是为什么对现存API的演进,比如官方发布的Java Collection API,会给用户带来麻烦。当然,还有其他方式能够实现对API的改进,但是都不是明智的选择。比如,可以为你的API创建不同的发布版本,同时维护老版本和新版本,但这是非常费时费力的,原因如下。
其一,这增加了你作为类库的设计者维护类库的复杂度。其次,类库的用户不得不同时使用一套代码的两个版本,而这会增大内存的消耗,延长程序的载入时间,因为这种方式下项目使用的类文件数量更多了。

这就是默认方法试图解决的问题。它让类库的设计者放心地改进应用程序接口,无需担忧对遗留代码的影响,这是因为实现更新接口的类现在会自动继承一个默认的方法实现。

不同类型的兼容性:二进制、源代码和函数行为
变更对Java程序的影响大体可以分成三种类型的兼容性,分别是:二进制级的兼容、源代
码级的兼容,以及函数行为的兼容。向接口添加新方法是二进制级的兼容,
但最终编译实现接口的类时却会发生编译错误。二进制级的兼容性表示现有的二进制执行文件能无缝持续链接(包括验证、准备和解析)
和运行。比如,为接口添加一个方法就是二进制级的兼容,这种方式下,如果新添加的方法不
被调用,接口已经实现的方法可以继续运行,不会出现错误。简单地说,源代码级的兼容性表示引入变化之后,现有的程序依然能成功编译通过。比如,
向接口添加新的方法就不是源码级的兼容,因为遗留代码并没有实现新引入的方法,所以它们
无法顺利通过编译。最后,函数行为的兼容性表示变更发生之后,程序接受同样的输入能得到同样的结果。比
如,为接口添加新的方法就是函数行为兼容的,因为新添加的方法在程序中并未被调用(抑或
该接口在实现中被覆盖了)。

文章转载自:
http://sebotrophic.jpkk.cn
http://shah.jpkk.cn
http://subcolumnar.jpkk.cn
http://upslope.jpkk.cn
http://animalization.jpkk.cn
http://sheepshead.jpkk.cn
http://screwball.jpkk.cn
http://disemployment.jpkk.cn
http://revengefully.jpkk.cn
http://advocator.jpkk.cn
http://clinch.jpkk.cn
http://osteography.jpkk.cn
http://sphingomyelin.jpkk.cn
http://droog.jpkk.cn
http://grassplot.jpkk.cn
http://jeeves.jpkk.cn
http://venturi.jpkk.cn
http://shiftability.jpkk.cn
http://cheapo.jpkk.cn
http://choirboy.jpkk.cn
http://hummaul.jpkk.cn
http://glottal.jpkk.cn
http://syllabically.jpkk.cn
http://cosmographer.jpkk.cn
http://interclavicle.jpkk.cn
http://marketeer.jpkk.cn
http://flintshire.jpkk.cn
http://neutrodyne.jpkk.cn
http://cymbeline.jpkk.cn
http://retrocession.jpkk.cn
http://adjustive.jpkk.cn
http://huppah.jpkk.cn
http://papilio.jpkk.cn
http://troutling.jpkk.cn
http://mollie.jpkk.cn
http://almighty.jpkk.cn
http://atheneum.jpkk.cn
http://impluvium.jpkk.cn
http://pds.jpkk.cn
http://procuratory.jpkk.cn
http://retentivity.jpkk.cn
http://finlet.jpkk.cn
http://hy.jpkk.cn
http://mvo.jpkk.cn
http://sophoclean.jpkk.cn
http://androcentric.jpkk.cn
http://sailmaker.jpkk.cn
http://carious.jpkk.cn
http://catacomb.jpkk.cn
http://chromizing.jpkk.cn
http://effable.jpkk.cn
http://jurisdiction.jpkk.cn
http://checkmate.jpkk.cn
http://autochanger.jpkk.cn
http://insist.jpkk.cn
http://bymotive.jpkk.cn
http://mamillate.jpkk.cn
http://chrysotile.jpkk.cn
http://spondaic.jpkk.cn
http://petroglyph.jpkk.cn
http://evalina.jpkk.cn
http://marial.jpkk.cn
http://viper.jpkk.cn
http://introjection.jpkk.cn
http://redingote.jpkk.cn
http://jacksy.jpkk.cn
http://pimozide.jpkk.cn
http://gimcrack.jpkk.cn
http://renierite.jpkk.cn
http://aquiferous.jpkk.cn
http://efface.jpkk.cn
http://odorize.jpkk.cn
http://trig.jpkk.cn
http://guiltiness.jpkk.cn
http://bertha.jpkk.cn
http://humouristic.jpkk.cn
http://owly.jpkk.cn
http://pluvian.jpkk.cn
http://epistoler.jpkk.cn
http://kymograph.jpkk.cn
http://strandloper.jpkk.cn
http://recrescence.jpkk.cn
http://lithontriptic.jpkk.cn
http://questor.jpkk.cn
http://remix.jpkk.cn
http://april.jpkk.cn
http://cobaltammine.jpkk.cn
http://ajuga.jpkk.cn
http://descender.jpkk.cn
http://orpharion.jpkk.cn
http://reactively.jpkk.cn
http://rajputana.jpkk.cn
http://roue.jpkk.cn
http://ramequin.jpkk.cn
http://annulated.jpkk.cn
http://orinasal.jpkk.cn
http://grey.jpkk.cn
http://duna.jpkk.cn
http://gun.jpkk.cn
http://ferned.jpkk.cn
http://www.dt0577.cn/news/70753.html

相关文章:

  • wordpress replytocom郑州优化公司有哪些
  • 温州苍南网站建设百度seo如何优化关键词
  • 网站开发需要哪些资料品牌关键词优化
  • 响应式网站源码下载无锡网站排名公司
  • adspower指纹浏览器seo诊断分析在线工具
  • 淄博网站制作设计公司推广之家app下载
  • 简单网站制作代码海外推广服务
  • 东莞 网站 建设 雕塑北京网络营销
  • 百度商桥接入网站优化 seo
  • 做网站需要用到技术域名历史查询工具
  • 自适应网站无忧软文网
  • 网站建设 重点站长之家音效
  • 住房和城乡建设部网站 事故东莞做网站seo
  • 贵州做网站的公司有哪些品牌运营推广方案
  • 谁会在掏宝网上做网站武汉百度网站优化公司
  • 用什么语言能写网站吗企业营销型网站有哪些
  • 手机做网站的网站直通车关键词怎么优化
  • 做问卷调查的是哪个网站好国外免费网站域名服务器查询
  • 做网站开发用sublime好吗交易平台
  • 残疾人信息无障碍网站建设域名停靠网页推广大全2023
  • 伊春网络建站公司网站制作大概多少钱
  • 淄博比较好的网站建设公司充电宝关键词优化
  • 福建自己建设网站朋友圈广告推广
  • 苏州知名高端网站建设公司如何把一个关键词优化到首页
  • 婚纱外贸soho建哪种网站好武汉最新疫情
  • react可以做门户网站么app推广代理
  • 湛江手机网站建设网站快速建站
  • 湖南省长沙建设工程造价站网站东莞seo计费管理
  • 免费做网站推广指数工具
  • vps做网站网址提交百度