2016-06-30 13 views
0

このコードスニペットに関連してわからない動作が発生しています。より正確には、演算子がタイプProjectionの場合(すなわち、n.isProjection()が真の場合)、private double getUniqueCost(final Node p)というシグニチャを持つメソッドではなく、private double getUniqueCost(final Projection p)というシグニチャを持つメソッドを呼び出すことが、getUniqueCostメソッドの呼び出しを予期していました。オーバーロードの混乱する動作

ProjectionはNodeのサブクラスであることに注意してください。

ここでは、2つの前述の方法のためのコード:実際に第二メソッドを呼び出すために管理するための唯一の方法は、次のように最初の方法を変更することであった

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

具体的な方法(on例えば、Projectionのパラメータを受け入れます。私は、Javaの型システムを見ていたので、それがしばらくされている

、私の容疑者は、式全体child.isJoin() ? n.getChildren().iterator().next() : ((Projection) n)が、左サイドの部分にそれらのタイプは確かにNodeで、Nodeとして入力されていることです。

誰でも確認できますか?いいえ、ここで起こっていることをよりよく理解していますか?

さらに、コードの2番目のバージョンを書くために、よりコンパクトな(エレガントな)方法があるのでしょうか?

答えて

1

三元条件式のタイプ - child.isJoin() ? n.getChildren().iterator().next() : ((Projection) n) - は、n.getChildren().iterator().next()((Projection) n)の両方に割り当てることができるタイプです。したがって、一方がNodeで他方がProjectionである場合、ProjectionをサブクラスNodeとすると、式のタイプはNodeとなります。

あなたの第二のスニペットは、ビットを短縮することができます:Projectionnキャスト

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

は、オーバーロードgetUniqueCost(final Projection p)メソッドが呼び出されます十分です。中間変数は必要ありません。

+0

これは私が式の静的型付けに念頭に置いていたものですが、実行時に動的な型定義が少し洗練され、どの「分岐」が取られるかを知っていると思いました。どうやら私はあまりにも多くを期待していた。もう一つのヒントもありがとうございます。 –

関連する問題