7

我正在尝试使用在clojuregen-class中覆盖此类compare(WriteableComparable a, WriteableComparable b)中的方法。复杂性来自此方法重载 3 次的事实:

  • 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)而不是预期的compare(WritableComparable a, WritableComparable b))。作为参考Object版本compare调用通过WriteableComparable版本。

NPE 完全有可能来自其他东西,但我至少已将其范围缩小到这个 clojure 代码(当我使用相应的 Java 版本运行它时,一切正常)。

有没有办法指定应该使用哪个重载版本的方法?

(我尝试:methods在调用中添加一个子句gen-class,但我了解到应该只声明新方法,而不是超类方法。)

4

1 回答 1

9

有一种机制可以使用gen-class并允许覆盖相同的重载方法。除了前缀和方法名称之外,我们还可以使用包含参数类型的名称来定义变量/函数。要覆盖一个方法,foo(String s, Object o)我们可以定义一个名为-foo-String-Object. 代码将在回退到-foo. 这至少记录在Clojure 邮件列表线程之一中

实际上,这意味着您可以编写如下代码:

(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 回答