7

clojureでこのクラスのメソッドgen-classをオーバーライドするために使用しようとしています。複雑なのは、このメソッドが 3 回オーバーロードされているという事実から来ています。compare(WriteableComparable a, WriteableComparable b)

  • int compare(WritableComparable a, WritableComparable b)
  • int compare(Object a, Object b)
  • int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2)

これまでのところ、私の試みは次のようになります。

(gen-class
 :name comparators.MyWriteableComparator
 :extends org.apache.hadoop.io.WritableComparator
 :exposes-methods {compare superCompare}
 :prefix "interop-")

(defn interop-compare
  ([this a b c d e f]
     (.superCompare this a b c d e f))
  ([this ^WritableComparable w1 ^WritableComparable w2]         
     (.compareTo (.getSymbol ^SymbolPair w1) 
                 (.getSymbol ^SymbolPair w2))))

compare(Object a, Object b)すべてがコンパイルされますが、実行すると null ポインター例外が発生します。これは、間違ったメソッド (つまり、意図した の代わりに)をオーバーライドしたためだと思われcompare(WritableComparable a, WritableComparable b)ます。参考までに、 のObjectバージョン から バージョン までをcompare呼び出しますWriteableComparable

NPE が別のものから来ている可能性は十分にありますが、少なくともこの clojure コードに絞り込みました (対応する Java バージョンで実行すると、問題なく動作します)。

メソッドのどのオーバーロードされたバージョンを使用するかを指定する方法はありますか?

:methods(呼び出しに句を追加しようとしましたgen-classが、スーパークラス メソッドではなく、新しいメソッドのみを宣言する必要があることを学びました。)

4

1 に答える 1

9

gen-class同じアリティのオーバーロードされたメソッドと連携してオーバーライドできるメカニズムがあります。プレフィックスとメソッド名に加えて、引数の型を含む名前で vars / functions を定義できます。メソッドをオーバーライドするfoo(String s, Object o)には、 という名前の var を定義できます-foo-String-Object。コードは、このように命名された var を探してから、 にフォールバックし-fooます。これは、Clojure メーリング リストのスレッドの少なくとも 1 つに文書化されています。

実際には、これは次のようなコードを記述できることを意味します。

(defn interop-compare [this a b c d e f]
  (do-array-compare))

(defn interop-compare-Object-Object [this a b]
  (do-object-compare))

(defn interop-compare-WritableComparable-WritableComparable [this a b]
  (do-writable-comparable-thing))
于 2015-09-25T22:20:19.813 に答える