令人困惑的重载行为

时间:2016-06-30 10:35:23

标签: java types overloading

我遇到了与此代码段无关的行为。更准确地说,我期望调用getUniqueCost方法来处理运算符类型为Projection的情况(即n.isProjection()为真时)调用具有as的方法签名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

有人可以证实吗?如果不是,你对这里发生的事情有了更好的了解吗?

另外,有没有办法让代码的第二版更紧凑(优雅?)?

1 个答案:

答案 0 :(得分:1)

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

您的第二个代码段可以缩短一点:

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

n投射到Projection就足以获得调用的重载getUniqueCost(final Projection p)方法。您不需要中间变量。