2016-06-30 56 views
0

我遇到了一個我不明白的與此代碼段有關的行爲。更確切地說,我期待getUniqueCost方法適用於運營商類型爲Projection(即,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()); 
} 

鑑於實際調用該方法之前,中投被執行(即,由值語義,其中的參數都在評估方法本身之前評估調用),我期待它足以調用最具體方法(上e接受Projection類型的參數)。

它已經有一段時間我看了一下Java的類型系統,我懷疑是整個表達式child.isJoin() ? n.getChildren().iterator().next() : ((Projection) n)的類型爲Node,由於左邊的類型確實Node

有人可以證實嗎?如果不是,你是否對這裏發生的事情有了更好的瞭解?

另外,有沒有辦法讓編寫代碼的第二版本更緊湊(優雅?)的方式?

回答

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

鑄造nProjection足夠的得到所謂的重載getUniqueCost(final Projection p)方法。你不需要一箇中間變量。

+0

這就是我對錶達式的靜態類型的想法,但是我在某種程度上期望在運行時動態類型更精緻一點,知道將要採用哪個「分支」。顯然我期待太多。還要感謝另一個提示,沒錯。 –