java - 用于重载和覆盖方法的 Clojure gen-class

标签 java clojure interop gen-class

我正在尝试使用 gen-class 覆盖 this class 中的 compare(WriteableComparable a, WriteableComparable b) 方法在 Clojure 中。复杂之处在于该方法被重载了 3 次:

  • int compare(WritableComparable a, WritableComparable b)
  • int 比较(对象 a,对象 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))。 For reference , Object 版本的 compare 调用到 WriteableComparable 版本。

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

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

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

最佳答案

有一种机制可以与 gen-class 一起使用,并允许覆盖相同数量的重载方法。除了前缀和方法名称之外,我们还可以使用包含参数类型的名称来定义变量/函数。要覆盖像 foo(String s, Object o) 这样的方法,我们可以定义一个名为 -foo-String-Object 的变量。代码将在回退到 -foo 之前寻找这样命名的 var。这至少记录在 one of the Clojure mailing list threads 中.

在实践中,这意味着您可以编写如下代码:

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

关于java - 用于重载和覆盖方法的 Clojure gen-class,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32773861/

相关文章:

java - JSF 日历选择整周

clojure - 在 clojure 中使用非命名空间符号

c++ - 在 C++ dll 中查找外部调用

java - Spring Data Elasticsearch是否支持日期字段的多种日期格式

java - com.google.gson 包不存在

clojure - 您将如何编写 Clojure SSH 客户端?

c# - 挂接到事件时 C# 中的 COMException

c# - HRESULT 异常 : 0x8002000B (DISP_E_BADINDEX) for System. Runtime.InteropServices.COMException

java - 如何使用 Derby 创建内存数据库表?

Windows 上的 Clojure、Leiningen 和 CLASSPATH