5
class SimpleTest {
    void met( Object a ) {
        println "Object"
    }

    void met( String b ) {
        println "String"
    }

    static main( args ) {
        SimpleTest i = new SimpleTest()
        i.met(null)
    }
}

このコードは、出力「オブジェクト」を生成します。メソッドの最も特殊化されたバージョンは選択されません。この場合、String は Object よりも特殊化されているため、この規則は適用されません。

4

1 に答える 1

8

Groovy は距離計算アプローチを使用します。基本的に、クラスとインターフェイスがグラフのノードであり、それらが継承関係によって接続されていると想像すると、指定された引数の型 (引数の実行時の型) からパラメーターの型 (静的) までの距離を探します。メソッドのパラメーターが持つタイプ)。接続にはさまざまな重みがあります。基本的に、スーパークラスに行くことは、私が思うに3の距離を意味し、インターフェース1まで、プリミティブをラップすることも1、vargsラッピングにも重みがあります(実際にはグラフで表すことはできません。ちょっと下手な画像ですみません)

null の場合、これはもちろん機能しません。ここでは、代わりにパラメーター型から Object までの距離を調べます。null 以外のケースが最も可能性のある特別な方法ですが、代わりに最も一般的な方法を null 部分に使用します。Java では、通常、静的型を使用するか、キャストを使用して、選択対象を確実にします。Groovy には静的な型がなく、何が最も特別なのかを正しく判断できないことがよくあります。したがって、その場合の代わりに最も一般的なアプローチを決定しました。それは一般的に非常にうまく機能します。

オブジェクトは一種のフォールバックのようなもので、一元的な null 処理を可能にします。将来のバージョンでは、明示的な null 型の使用を許可する可能性があります。

多くの場合、クラスの距離アプローチを直接見ることができますが、インターフェイスの場合はもう少し複雑です。基本的に、アルゴリズムは次のようになります。現在のクラスが探しているインターフェイスを直接実装している場合、距離 1 に一致します。クラスが実装するインターフェイスのいずれかに、親として探すインターフェイスがある場合は、"私たちが距離としてそこにいるまで。しかし、私たちは最短距離を探します。したがって、スーパークラスも同じように見えます。そこからの検索結果は、その距離 +1 になります (スーパー クラス ホップの場合)。スーパー クラスの検索が、実装されているインターフェイスでの検索よりも短い距離を提供する場合、代わりにスーパー クラスの検索結果が取得されます。

インターフェイスでの null の処理については...インターフェイスが別のインターフェイスを拡張しない場合、Object までの距離はここでは 1 です。その場合、親インターフェイスの距離 +1 です。複数のインターフェースを延長すると、やはり最短経路になります。

null の List と Integer を見てみましょう。
List extends Collection、Collection extends Iterable、Iterable には親がありません。これにより、Iterable の距離は 1、Collection の距離は 2、List の距離は 3 になります。整数は数値を拡張し、数値はオブジェクトを拡張します。2 回ホップするので、ここでは距離が 6 (2x3) になり、他のケースよりもはるかに大きくなります。はい、それは一般的にインターフェイスを好むことを意味します。この方法は、実際のプログラミングの実践に最も近いことが証明されているため、実際には実用的な理由でこれを行います。

于 2013-02-19T14:37:24.147 に答える