I am experiencing a behaviour that I do not understand related to this code snippet. More precisely, I was expecting the call of `getUniqueCost`

method for the case in which the operator is of type `Projection`

(that is, when `n.isProjection()`

is true) to be calling the method having as signature `private double getUniqueCost(final Projection p)`

instead of that having signature `private double getUniqueCost(final Node p)`

.

Note that Projection is a subclass of Node.

Here the code for the two aforementioned methods:

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()); }

The only way to actually manage to call the second method was to modify the first method as follows (the omitted code is the same as before):

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()); }

Given that the cast is executed before actually calling the method (that is, call by value semantics, where the parameters are evaluated before evaluating the method itself), I was expecting it to be sufficient to call the most specific method (the one accepting a parameter of type `Projection`

).

It has been a while since I had a look at the type system of Java, my suspect is that the whole expression `child.isJoin() ? n.getChildren().iterator().next() : ((Projection) n)`

is typed as `Node`

, due to the left part those type is indeed `Node`

.

Does anybody can confirm it? If no, do you have a better understanding of what’s going on here?

In addition, is there a way to have a more compact (elegant?) way of writing the second version of the code?

## Answer

The type of your ternary conditional expression – `child.isJoin() ? n.getChildren().iterator().next() : ((Projection) n)`

– is a type that both `n.getChildren().iterator().next()`

and `((Projection) n)`

can be assigned to. Therefore, if one of them is `Node`

and the other `Projection`

, assuming `Projection`

is a sub-class of `Node`

, the type of the expression is `Node`

.

Your second snippet can be shortened a bit :

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

Casting `n`

to `Projection`

is enough the get the overloaded `getUniqueCost(final Projection p)`

method called. You don’t need an intermediate variable.