java - 不允许使用站点注入(inject)扩展方法到 Java 8 的设计考虑是什么?

标签 java java-8 extension-methods api-design default-method

我们有默认方法,也称为防御方法和“虚拟扩展方法”。

虽然我很欣赏默认方法的巨大值(value)(在某些方面甚至比 C# 对应方法更强大),但我想知道是什么决定不允许在不访问其源代码的情况下扩展现有接口(interface)。

In one of his answers here in SO Brian Goetz 提到默认方法在很大程度上是为了方便和接口(interface)进化而设计的。因此,如果我们编写一个接口(interface),我们可以将通常必须放在单独类中的各种实用方法塞入其中。那么,为什么不多走一步,允许它用于不受我们控制的接口(interface)呢?

最佳答案

这是由一种哲学信念驱动的:API 设计者应该控制他们的 API。虽然从外部将方法注入(inject) API 确实很方便,但它破坏了 API 设计者对其 API 的控制。 (这有时被称为“猴子补丁”。)

关于术语:C#所说的“扩展方法”只是扩展方法的一种形式,并不是扩展方法的定义; Java 的默认方法也是扩展方法。主要区别是: C# 扩展方法是静态 并在使用站点 中注入(inject); Java 是虚拟声明站点。其次,C# 扩展方法被注入(inject)到类型中,而 Java 的默认方法是的成员。 (这允许您在 C# 中将 sum() 方法注入(inject) List<int> 而不会影响其他 List 实例化。)

如果您已经习惯了 C# 方法,很自然地会假设这是执行此操作的“正确”或“正常”或“真实”方法,但实际上,它只是许多可能方法中的一种。正如其他张贴者指出的那样,与 Java 的默认方法相比,C# 扩展方法有一些非常严重的缺点(例如,反射可发现性差、通过文档的可发现性差、不可覆盖、需要特别的冲突管理规则)。所以相比之下,这里的 Java 玻璃杯已经超过一半了。

关于java - 不允许使用站点注入(inject)扩展方法到 Java 8 的设计考虑是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29466427/

相关文章:

c# - 我怎样才能使这个扩展方法更通用?

c# - 旋转数组集合

c# - 将属性用于通用约束

java - 使用流对内部对象的 Map 属性进行分组?

java - Java 8 中的多个空值检查

java - 在 Tapestry 中渲染一个请求参数

Java:在字符串中查找字符串

java - DrJava:无法使用 JDK8.0 运行代码

java - 创建扫雷,更改难度时如何重置棋盘。

java - 在查询中使用不同关键字的重复条目