警告:一旦阅读,您将无法看不到它

我在上一篇博客文章中讨论了默认方法的多重继承,以及它们在编译和运行时的行为。 这周,我将研究如何使用默认方法进行真正的继承,实际上,默认方法并不是为这种方法而设计的。 出于这个原因,请您自担风险阅读这些行,并不意味着这是要遵循的模式,同样也并不意味着相反。 我在这里写的是一些可以使用Java 8编写的编码技术,但是它们的可用性至少对我来说值得怀疑。 我也有点害怕从瓶子里放一些香水 ,但另一方面,那些香水根本就不会留在那里。 总有一天有人会说出来。 至少我附上了警告标志。

样本问题

几年前,我在一个应用程序上工作,该应用程序使用了许多不同类型的对象,每个对象都有一个名称。 在许多课程开始包含之后

public String getName(){...}
public void setName(String name){...}

复制粘贴代码的方法只是设置者和获取者,只是让整个房间难以忍受。 因此我们创建了一个类

class HasName {public String getName(){...}public void setName(String name){...}
}

每个具有名称的类都只是扩展了该类。 实际上,它长时间没有工作。 有些类已经扩展了其他类。 在那种情况下,我们只是试图在继承行中将HasName向上移动,但是在某些情况下,它只是行不通。 当我们到达最高峰时,我们意识到那些阶级及其后代没有名字,为什么要强迫他们呢? 老实说,在现实生活中,这比仅仅拥有名字要复杂得多。 如果只是名称,我们可以将其与其他具有名称的类一起使用。 事情变得更复杂了,这只会使话题变得更加复杂,并让我相信:它将变得足够复杂。

简介:我们无法实现在某些备用类中实现的某些对象的名称。 但是现在我们可以使用默认方法做到这一点。

具有默认实现的HasName接口

默认方法仅提供默认功能。 默认方法可以访问this变量, this变量始终是实现接口的对象,并且代表该方法被调用。 如果有一个接口I和C类实现接口,当一个上的方法C c对象被调用变量this实际上是对象c 。 您将如何实现getName()setName()

这些是访问对象中的String变量的设置方法和获取方法。 您不能从界面访问它。 但是,将值存储在对象中并不是绝对必要的。 唯一的要求是,为对象设置的任何内容都将相同。 我们可以将值存储在其他位置,每个对象实例一个。 因此,我们需要一些可以与对象配对的值,并且该值的生存期必须与该对象的生存期相同。 它会响吗?

这是一个弱哈希表! 是的。 并使用它可以轻松实现HasName接口。

public interface HasName {class Extensions {private static final WeakHashMap<HasName, String> map = new WeakHashMap<>();}default void setName(String name) {Extensions.map.put(this, name);}default String getName() {return Extensions.map.get(this);}
}

您所要做的就是在该类实现的接口列表的末尾写: ,HasName ,它神奇地拥有了。

在此示例中,唯一存储的值是String 。 但是,您可以拥有任何类而不是String并且不仅可以实现setter和getter,而且可以实现对该类执行某些操作的任何方法。 大概这些实现将在类中实现,并且默认方法将仅委托。 您可以将类放置在其他位置,也可以将其作为内部类放在接口中。 品味和风格的问题

结论

接口不能具有实例字段。 为什么? 因为在那种情况下,它们不是接口而是类。 Java没有多重实现继承。 也许有,但是“请不要使用”。 默认方法是技术错误。 您可以称其为妥协。 使用功能方法扩展时,需要一些东西来保持JDK库的向后兼容性。 仍然可以使用弱哈希映射模拟接口中的字段,以访问要委派的字段和方法的继承类“ vtable”。 有了它,您可以进行真正的多重继承。 母亲总是警告您的类型。 我告诉你队友!

另一个警告:以上实现不是线程安全的。 如果尝试在多线程环境中使用它,则可能会收到ConcurrentModificationException,或者甚至可能会在弱哈希映射上调用get()陷入无限循环,并且永不返回。 我不告诉您在这种情况下如何解决弱哈希映射的使用问题。 或者,好吧,我改变了主意,然后做了:只使用默认方法使用的默认方法。

翻译自: https://www.javacodegeeks.com/2014/04/how-not-to-use-java-8-default-methods.html

如何不使用Java 8默认方法相关推荐

  1. Java 8默认方法会破坏你的(用户的)代码

    Java 8的默认方法试图尝试更进一步简化Java API.不幸的是,这一最近的语言扩展带来了一系列复杂的规则,但只有少部分Java开发者意识到这一点.这篇文章告诉你为什么引入默认方法会破坏你的(用户 ...

  2. java8 默认方法_如何不使用Java 8默认方法

    java8 默认方法 警告:一旦阅读,您将无法看不到它 我在上一篇博客文章中讨论了默认方法的多重继承,以及它们在编译和运行时的行为. 这周,我将研究如何使用默认方法进行真正的继承,实际上,默认方法并非 ...

  3. Java 8默认方法可能会破坏您的(用户)代码

    乍一看, 默认方法为Java虚拟机的指令集带来了一个很棒的新功能. 最后,库开发人员能够开发已建立的API,而不会对其用户代码造成不兼容性. 使用默认方法,当将新方法引入该接口时,任何实现库接口的用户 ...

  4. java 二义性_Java接口默认方法带来的问题分析【二义性问题】

    本文实例分析了Java接口默认方法带来的问题.分享给大家供大家参考,具体如下: 一 点睛 Java 8中,如果一个类实现两个或多个接口,即"变相"的多继承,但是若其中两个接口都包含 ...

  5. java 代码 二义性是什么_Java接口默认方法带来的问题分析【二义性问题】

    本文实例分析了Java接口默认方法带来的问题.分享给大家供大家参考,具体如下: 一 点睛 Java 8中,如果一个类实现两个或多个接口,即"变相"的多继承,但是若其中两个接口都包含 ...

  6. 注解默认继承_默认方法和多重继承

    注解默认继承 最近卢卡斯JOOQ埃德尔发布和文章有关嵌套类及其使用. 这是一个有趣的话题,他的文章一如既往地有趣并且值得一读. 只有一个简短的声明我无法同意,我们有一个简短的回复链,导致了默认方法,以 ...

  7. java8接口写静态方法_Java 8接口更改–静态方法,默认方法

    java8接口写静态方法 Java 8 interface changes include static methods and default methods in interfaces. Prio ...

  8. 深入理解Java 8 Lambda(语言篇——lambda,方法引用,目标类型和默认方法)

    作者:Lucida 微博:@peng_gong 豆瓣:@figure9 原文链接:http://zh.lucida.me/blog/java-8-lambdas-insideout-language- ...

  9. Java 8 (8) 默认方法

    传统上,Java程序的接口是将相关方法按照预定组合到一起的方式.实现接口的类必须为接口中定义的方法提供一个实现,或者从父类中集成它的实现.但是,一旦类库的设计者需要更新接口,向接口中加入新的方法时候, ...

最新文章

  1. 调控微生物改善土壤,生物制剂能否开启农业新篇章?
  2. VT-x/AMD-V 硬件加速器已被启动,但当前处于无效状态
  3. 移动通信考前预习_第2章_蜂窝技术
  4. C语言 指针声明和定义 - C语言零基础入门教程
  5. MySQL Index Condition Pushdown
  6. drool 7.x 属性 : agenda-group
  7. Yarn的资源调度与隔离
  8. python将一个文件夹下图片到另外一个文件夹下
  9. 会c 学plc编程语言,想学PLC编程?先弄清5种PLC专用语言!
  10. 相关不是因果,哪又是啥?
  11. LeetCode 776. Split BST
  12. SpringBoot整合ThymeLeaf前后端分离使用案例
  13. run()方法和start()方法的区别
  14. vue基础:ElementUI的表单
  15. 如何查看服务器的公网IP
  16. 十个人有多少种不同组合?
  17. OpenLayers添加地图标记
  18. 【FICO系列】SAP FICO模块-财务账期的打开和关闭
  19. 【javaScript】JavaScript中一个等号、二个等号、 三个等号 的区别(详细例子)
  20. 灰色预测模型python_python实现灰色预测模型(GM11)——以预测股票收盘价为例

热门文章

  1. 键盘录入一个正整数,把它的各个位上的数字倒着排列形成一个新的整数并输出。 例如:12345 数出54321 78760 输出6787(0省去)
  2. python自动配置文件_【python接口自动化】- ConfigParser配置文件的使用
  3. redis集群信息分析-cluster info-cluster nodes
  4. 转:微服务设计、拆分原则
  5. camel apache_如何使用Apache Camel,Quarkus和GraalVM快速运行100个骆驼
  6. 移位操作提高代码的可读性_本地记录或类,以提高流操作的可读性
  7. java全局变量和局部变量_Java 10 –局部变量类型推断
  8. aws lambda_跑来跑去:假人与AWS Lambda的第一次接触
  9. java使用缓冲区读取文件_在Java中使用Google的协议缓冲区
  10. spring flux_Spring Web-Flux – Cassandra后端的功能样式