【问题标题】:Confusing behaviour of overloading令人困惑的重载行为
【发布时间】:2016-06-30 10:35:22
【问题描述】:

我遇到了与此代码 sn-p 相关的我不理解的行为。更准确地说,我期望在运算符类型为Projection 的情况下调用getUniqueCost 方法(即,当n.isProjection() 为真时)调用具有签名private double getUniqueCost(final Projection p) 而不是签名的方法有签名private double getUniqueCost(final Node p)

请注意,Projection 是 Node 的子类。

这里是上述两种方法的代码:

private double getUniqueCost(final Node n){
    if(n.isScan())
        return getUniqueCost(estimateCardinality(n));
    if(n.isJoin())
        return getUniqueCost((NJoin) n);
    if(n.isUnion())
        return getUniqueCost((Union) n);
    if(n.isMaterialization())
        return getUniqueCost(n.getChildren().iterator().next());        
    if(n.isProjection()){ 
        return getUniqueCost(child.isJoin() ? 
            n.getChildren().iterator().next() : ((Projection) n));
    }
    throw new IllegalArgumentException("Unknown node type: " + n.getOperator());
}

private double getUniqueCost(final Projection p){
    return getUniqueCost(estimateCardinality(p)) + 
            getUniqueCost(p.getChildren().iterator().next());
}

真正设法调用第二种方法的唯一方法是修改第一种方法如下(省略的代码与之前相同):

private double getUniqueCost(final Node n){
    [...]
    if(n.isProjection()){ 
        final Node child = n.getChildren().iterator().next();
        if(child.isJoin()){
            return getUniqueCost(child);
        }

        final Projection proj = (Projection) n;
        return getUniqueCost(proj);
    }
    throw new IllegalArgumentException("Unknown node type: " + n.getOperator());
}

鉴于强制转换是在实际调用方法之前执行的(即按值调用语义,其中在评估方法本身之前评估参数),我期望它足以调用最具体的方法(一个接受 Projection 类型的参数)。

看了Java的类型系统已经有一段时间了,我怀疑整个表达式child.isJoin() ? n.getChildren().iterator().next() : ((Projection) n)被键入为Node,因为左边的那个类型确实是Node

有人可以确认吗?如果没有,您对这里发生的事情有更好的了解吗?

另外,有没有一种更紧凑(优雅?)的方式来编写第二版代码?

【问题讨论】:

    标签: java types overloading


    【解决方案1】:

    三元条件表达式的类型 - child.isJoin() ? n.getChildren().iterator().next() : ((Projection) n) - 是n.getChildren().iterator().next()((Projection) n) 都可以分配的类型。因此,如果其中一个是Node,另一个是Projection,假设ProjectionNode的子类,那么表达式的类型就是Node

    你的第二个 sn-p 可以缩短一点:

        if(child.isJoin()){
            return getUniqueCost(child);
        } else {
            return getUniqueCost((Projection) n);
        }
    

    n 转换为Projection 就足以获取调用的重载getUniqueCost(final Projection p) 方法。您不需要中间变量。

    【讨论】:

    • 这是我对表达式的静态类型的想法,但不知何故,我期望在运行时动态类型会更加精致,知道将采用哪个“分支” .显然是我期望太高了。也感谢其他提示,没错。
    猜你喜欢
    • 2011-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-22
    • 1970-01-01
    • 1970-01-01
    • 2014-10-11
    相关资源
    最近更新 更多