Java 8默认方法会破坏你的(用户的)代码
作者:网络转载 发布时间:[ 2015/6/24 13:35:22 ] 推荐标签:编程语言 Java
使用这个新的接口,用户可以更新他的代码,采用默认方法来代替原来的适配器类。通过使用接口代替适配器类的好的结果是,该类可以继承(extend)其它的类,而不是特定的适配器。现在我们进行实践,移植MyInput类使其使用默认方法。因为我们现在能继承其它类了,所以我们继承一个第三方的基础类。我们这里不需要关心这个基础类的作用,我们可以假设这个对我们的功能是有意义的。
class MyInput extends ThirdPartyBaseClass implements SimpleInput {
@Override
public void foo() {
// do something ...
}
@Override
public void bar() {
SimpleInput.super.bar();
// do something additionally ...
}
}
为了实现原始类相似的功能,我们使用Java 8的新的语法来调用指定接口的默认方法。同时,将我们方法中的一些逻辑移到基础类中去。此时,你可能拍着我的肩膀说,这是一次非常好的重构!
我们相当成功的使用了该库。但是,维护人员需要增加另一个接口来提供更多的功能。该接口被 ComplexInput 接口所代替,这个接口继承自 SimpleInput 接口,并增加了新的方法。因为默认方法通常来说是可以很安全的添加的,因此,维护人员覆盖了 SimpleInput 的默认方法,提供了一个更好的默认方法。毕竟,这对于采用适配器类的方式来说是很平常的事情。
interface ComplexInput extends SimpleInput {
void qux();
@Override
default void bar() {
SimpleInput.super.bar();
// so complex, we need to do more ...
}
}
新的特性带来了非常好的效果以至于维护 ThirdPartyBaseClass 的人也决定依赖该库。为了完成这项工作,它在 ThirdPartyLibrary 中实现了 ComplexInput 接口。
但是这对 MyInput 类来说意味着什么呢?为了隐式的实现 ComplexInput 接口,可继承 ThirdPartyBaseClass 类,但是调用 SimpleInput 的默认方法突然变成非法的了。结果,用户的代码不能通过编译。现在这种调用是被禁止的,因为Java认为这种在非直接子类中调用父类的父类的方法是非法的。你只能在 ComplexInput 中去调用该默认方法,但是,这要求你显示的在MyInput中实现该接口。对于库的用户来说,这种改变不是所预期的!
更奇怪的是,Java运行时却不做这种限制。JVM的校验器是允许一个编译好的类去调用 SimpleInput::foo 方法的,即使该类是通过继承更新后的 ThirdPartyBaseClass,从而隐式的实现了ComplexClass。这种限制只存在于编译器中。
我们从这里能学到什么东西呢?简单的说,确保不要在一个接口中覆盖另一个接口的默认方法,既不要用默认方法覆盖,也不要用抽象方法覆盖。总的来说,请谨慎使用默认方法。即使它使得Java的集合接口API轻易的发生了革命性的变化,但本质上讲,这种继承层级之间的方法调用,增加系统的复杂性。而在Java 7之前,你只需要沿着线性的类层级去查找真正调用的代码。只有当你觉得非常有必要的时候才去增加这种复杂性。
本文内容不用于商业目的,如涉及知识产权问题,请权利人联系SPASVO小编(021-61079698-8054),我们将立即处理,马上删除。
相关推荐
Java性能测试有哪些不为众人所知的原则?Java设计模式??装饰者模式谈谈Java中遍历Map的几种方法Java Web入门必知你需要理解的Java反射机制知识总结编写更好的Java单元测试的7个技巧编程常用的几种时间戳转换(java .net 数据库)适合Java开发者学习的Python入门教程Java webdriver如何获取浏览器新窗口中的元素?Java重写与重载(区别与用途)Java变量的分类与初始化JavaScript有这几种测试分类Java有哪四个核心技术?给 Java开发者的10个大数据工具和框架Java中几个常用设计模式汇总java生态圈常用技术框架、开源中间件,系统架构及经典案例等
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11热门文章
常见的移动App Bug??崩溃的测试用例设计如何用Jmeter做压力测试QC使用说明APP压力测试入门教程移动app测试中的主要问题jenkins+testng+ant+webdriver持续集成测试使用JMeter进行HTTP负载测试Selenium 2.0 WebDriver 使用指南