我们有默认方法,也被称为防御方法和“虚拟扩展方法”。
虽然我理解默认方法的巨大价值(在某些方面甚至比C#方法更强大),但我想知道为什么不允许扩展现有接口而不访问其源代码。
Brian Goetz在这里的一个答案中提到,默认方法的设计是为了方便和接口进化。因此,如果我们编写一个接口,我们就可以在那里填充我们通常必须放在一个单独类中的各种实用方法。那么,为什么不多做一步,允许它用于不在我们控制范围内的接口呢?
这是由一个哲学信念驱动的:API设计者应该控制他们的API。虽然在API中外部注入方法确实很方便,但它破坏了API设计者对其API的控制。(这有时被称为“补猴”。)
在术语上:C#所说的“扩展方法”只是扩展方法的一种形式,而不是扩展方法的定义;Java的默认方法也是扩展方法。主要区别在于:C#扩展方法是静态的,在使用现场注入;Java是虚拟的和声明站点的。其次,C#扩展方法被注入到类型中,而Java的默认方法是类的成员。(这允许您在C#中将sum()
方法注入到list
中,而不影响其他list
实例化。)
如果您已经习惯了C#的方法,那么假设这是“正确的”、“正常的”或“真实的”方法是很自然的,但实际上,这只是许多可能的方法中的一种。正如其他海报所指出的,与Java的默认方法相比,C#扩展方法有一些非常严重的缺陷(例如,反射发现性差,通过文档发现性差,不可重写,需要特别的冲突管理规则)。因此,相比之下,这里的Java玻璃远远超过了一半。
我们举个例子: 一个常见的解决方案是转移到一个抽象类,但是在我的具体案例中,我有一个枚举的接口,所以在这里不适用。我想这不是被忽略了,就是因为接口背后的原始想法,即它们是可用方法的“契约”,但我想我需要关于这是怎么回事的输入。 我读过“为什么Java 8接口方法中不允许使用”final“?”,其中说: 默认方法的基本思想是:它是具有默认实现的接口方法,派生类可以提供更具体的实现 与关联问题一样,由
问题内容: 我想知道Java中是否有特殊原因总是使用“ ”而不是“ ”来定义类型参数的界限。 例: 被禁止但是 是正确的。是什么原因呢? 问题答案: 在类“实现”还是“扩展”之间,通用约束语言没有语义差异。约束可能性是“扩展”和“超级”-也就是说,该类是可分配给其他类的对象(扩展),还是该类可从该类分配(超级)。
Java说: 所以说数组是协变的。但对于泛型,他们说: 因此它是不变量。但问题是,“泛型真的不变吗?”? 例如,如果我给出: 这意味着列表可以采用异常的子类型,例如这是有效的: 那么为什么泛型被称为不变量呢?
问题内容: 作为实验,我尝试扩展-array,如下所示: 在类本身中添加一些与排序,交换,子数组构建等有关的方法。但是我在编译时遇到了这个错误: 我很好奇:为什么Java不允许扩展数组? 问题答案: 扩展基本类型(例如a 或数组)会打开安全漏洞。如果Java允许您扩展数组,则采用数组的方法将变得不安全。这就是字符串为,而数组根本不能扩展的原因。 例如,您可以重写该方法,并返回不正确大小的数组。这有
在爪哇,its说: 所以数组被称为协变的。但对于泛型,他们说: 因此它是不变的。但问题是,“泛型真的是不变的吗”? 那为什么说泛型是不变的呢?
主要内容:1.考虑一:负负得正,2.考虑二:终态设计,3.考虑三:长尾效应,4.考虑四:存储周期,5.考虑五:AKF扩展,6.考虑六:服务自治,7.考虑七:应急预案,8.考虑八:故障隔离,9.考虑九:风险巡检,10.考虑十一严格准入1.考虑一:负负得正 如果把错误的逻辑改对了反而可能引起问题。 这种问题要避免最好的时机是初版设计和开发阶段就避免。除了设计阶段逻辑要清晰,代码要做好审查、加上单体测试等测试手段外,可以将中间结果用debug日志打印。建议自测阶段多用debug级别日志跑几遍,进行观察