【发布时间】:2017-05-27 14:50:17
【问题描述】:
我已经使用 Java 1.6(维护遗留工具)多年,并且刚刚开始迁移到 1.8。一大变化是 java.util.Collections 套件中的函数式方法。对我来说最大的担忧是我有几个集合扩展,它们在修改时应用了仔细的检查或算法。默认方法是否调用已定义的 put(..)、get(...)、remove(..) 等函数,还是我必须进行重大返工才能使其工作?
例如(忽略空检查等只包含值
public class LimitedMap extends HashMap<String, Integer>{
@Override
public Integer put(String key, Integer value){
if(value> 10) throw new IllegalArgumentException();
return super.put(key, value);
}
@Override
public Integer computeIfAbsent(String key, Function<? super String, ? extends Integer> mappingFunction) {
return super.computeIfAbsent(key, mappingFunction);
}
}
使用这对函数:我是否仍需要进行详细的覆盖并将新的检查放入 computeIfAbsent 函数?
【问题讨论】:
-
你不知道,无论如何它都可能改变,这就是为什么你应该支持组合而不是继承:jtechies.blogspot.fr/2012/07/…。如果您使用了组合,那么所有新添加的默认方法都会简单地委托给您自己的方法。
-
如果你想知道新的默认方法是做什么的,为什么不直接看源码呢? JDK 附带了 Java 运行时库的所有类的源代码,任何好的 IDE 都可以很容易地查看该源代码。您使用的 IDE 不错,对吧?
-
@Radiodef 您错过了重点:OP 的 Map 实现扩展了 HashMap,其中默认方法被覆盖。 HashMap 的 computeIfAbsent() 是否调用 put() 是一个实现细节,OP 不能依赖它。
-
@JBNizet 是的,你是对的。无论如何,我完全同意您对组成和授权的评论。例如,这可以用
AbstractMap轻松完成。 -
正如@JBNizet 所说,您不应该扩展不打算专门化的实现类。你要重复the failure of others。并不是 Java 8 没有引入这个示例问题,而是 Java 8,更新 20。这说明了实现细节是多么脆弱。另见Inheritance, composition and default methods...
标签: java collections lambda java-8