java - 为分层实体设计界面

标签 java interface java-8 hierarchical default-method

我必须为分层实体设计一个接口(interface):

interface HierarchicalEntity<T extends HierarchicalEntity<T>> {
    T getParent();
    Stream<T> getAncestors();
}

默认很容易实现getAncestors() getParent() 方面的方法以这样的方式前者会返回Stream所有的祖先。

实现示例:

default Stream<T> getAncestors() {
    Stream.Builder<T> parentsBuilder = Stream.builder();
    T parent = getParent();
    while (parent != null) {
        parentsBuilder.add(parent);
        parent = parent.getParent();
    }
    return parentsBuilder.build();
}

但我还需要包括 this进入流,这里出现了一个问题。 以下行不正确,因为 this类型为 HierarchicalEntity , 不是 T :

parentsBuilder.add(this); // type mismatch!

我怎样才能重新设计界面以制作getAncestors()包括 this进入结果?

最佳答案

这是创建自引用类型时反复出现的问题。在基类型(或接口(interface))中,您不能强制要求 this 的赋值与 T 兼容。

当然,如果您确信所有子类型都将满足该约束,则可以执行未检查的 thisT 的转换。但是,只要您需要将 this 引用为 T,就必须执行此未经检查的转换。

更好的解决方案是添加一个抽象方法,如

/**
    All subtypes should implement this as:

    public T myself() {
        return this;
    }
 */
public abstract T myself();

然后,只要您需要将自引用作为 T,就可以使用 myself() 而不是 this

default Stream<T> getAncestors() {
    Stream.Builder<T> parentsBuilder = Stream.builder();
    for(T node = myself(); node != null; node = node.getParent()) {
        parentsBuilder.add(parent);
    }
    return parentsBuilder.build();
}

当然,您不能强制子类正确实现 myself() 作为 return this;,但至少,您可以轻松验证它们是否在运行时执行:

assert this == myself();

这个引用比较是一个非常便宜的操作,如果 myself() 被正确地实现为总是返回 this,HotSpot 可以提前证明这个比较总是true 并完全省略检查。

缺点是每个特化都必须有 myself() { return this; 的冗余实现。 },但另一方面,它完全没有未经检查的类型转换。另一种方法是在基类中对 myself() 进行非抽象声明,如 @SuppressWarnings("unchecked") T myself() { return ( T)这个; } 将未经检查的操作限制在类型层次结构的单个位置。但是,你无法验证 this 是否真的是 T 类型......

关于java - 为分层实体设计界面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37078814/

相关文章:

c++ - CUDD C++ 接口(interface),用于将 bool 值转换为 BDD 和生成的最小项集(到割集)

java - 将 Java 8 与 Google App Engine SDK 结合使用

java - DateFormat 和 SimpleDateFormat 的 parse() 的区别

java - 无法在原始类型 void 上调用 forEach((<no type> de) -> {})

java - 字符串 url 编码两次,我无法获取初始字符串

java - 使用 Spring 中通过基本身份验证保护的 HTTP POST 方法

java - 按回归排序

java - 编写一个良好的接口(interface)以与特定技术分离……如何处理异常?

java - 有没有clojure IDE可以帮助自动补全Java对象的方法?

c# - 抽象类与接口(interface)的建议