Я испытываю поведение, которое я не понимаю, связанный с этим фрагментом кода. Точнее, я ожидал вызова метода getUniqueCost
для случая, когда оператор имеет тип Projection
(то есть, когда n.isProjection()
является истинным), чтобы вызвать метод, имеющий подписи private double getUniqueCost(final Projection p)
, вместо того, чтобы иметь подпись private double getUniqueCost(final Node p)
.Сложное поведение перегрузки
Обратите внимание, что Projection является подклассом узла.
Вот код для двух вышеупомянутых методов:
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());
}
Учитывая, что бросок выполняется до фактического вызова метода (то есть вызов по значению семантики, где параметры оцениваются прежде чем оценивать сам метод), я ожидал, что это будет достаточно, чтобы вызвать наиболее конкретный метод (e принимает параметр типа Projection
).
Это было некоторое время, так как я имел взгляд на типе системе Java, мои подозреваемый в том, что все выражении child.isJoin() ? n.getChildren().iterator().next() : ((Projection) n)
набираются в Node
, из-за левую часть того типа действительно Node
.
Кто-нибудь может это подтвердить? Если нет, у вас есть лучшее понимание того, что здесь происходит?
Кроме того, есть ли способ иметь более компактный (элегантный?) Способ написания второй версии кода?
Это то, что я имел в виду для статического ввода выражения, но я как-то ожидал, что во время выполнения динамическая типизация будет немного более утонченной, зная, какая «ветвь» будет принята. Видимо, я ожидал слишком многого. Спасибо также за другой совет, это верно. –