【问题标题】:Java interface to Clojure with proxy带有代理的 Clojure 的 Java 接口
【发布时间】:2018-04-09 02:26:54
【问题描述】:

我是 Clojure 的新手,我正在尝试实现 Clojure 的 Java 接口。具体这段代码

import javax.print.*;

class Test {

    public static void main (String [] args)
    {
        PrintService[] printServices = PrintServiceLookup.lookupPrintServices(null, null);
        System.out.println("Number of print services: " + printServices.length);

        for (PrintService printer : printServices)
            System.out.println("Printer: " + printer.getName()); 
    }
}

PrintService 是一个接口,PrintServiceLookup 是一个构造函数类。我对如何使用 reify 和代理感到困惑。我的目标是在我的系统上安装已安装的打印机。 谁能举例说明如何使用 reify 或代理?从文档中我了解到我必须加载界面,然后加载我想要使用的方法,但我无法让它工作。 从我理解的Java角度来看,我必须从PrintServiceLookup.lookupPrintServices()获取一个对象,然后从PrintService接口应用getName函数,然后打印它。 我的尝试到现在

(defn print-serv []
  (let [printS (proxy [PrintService PrintServiceLookup] []
       (getName [])
                 (lookupPrintServices [])
    )]
    (.println (System/out) (.getName printSe))
    )

    )

我很确定一切都是错误的,但我不明白具体化和代理是如何工作的,如果有人能更好地向我解释,我将不胜感激!

【问题讨论】:

    标签: clojure


    【解决方案1】:

    您发布的 Java 代码没有实现接口。看起来您只是在尝试调用静态方法并迭代结果:

    (let [printers (PrintServiceLookup/lookupPrintServices nil nil)]
      (println "Number of print services:" (count printers))
    
      (doseq [^PrintService p, printers]
        (println (.getName p)))
    

    doseq 循环也可以简单地写成:

    (doseq [p printers]
      ...)
    

    为了完整性,我只包含了^PrintService 类型提示。

    另外请注意,您不必写完整的(.println (System/out) ...)。 Clojure 有 println 快捷方式。

    【讨论】:

    • 你是对的,那行得通!!!谢谢!!但是在(doseq [^PrintService p, printers] 中,您实际上告诉coljure p 它属于PrintService 接口?那里到底发生了什么?
    • @narocath Np。乐意效劳。 ^PrintService 类型提示是可选的。它只是告诉编译器pPrintService。我通常在使用互操作时包含类型提示,即使它们是可选的。它让您的 IDE 为您提供更好的自动完成猜测,并允许您避免反射,这通常会导致更快的代码。如果您跳过提示,您的 IDE 可能会给出无法解析 .getName 的警告,这需要在运行时进行反射。
    • 我明白了,还有一个问题,当我应该加载界面时,我的意思是在这种特定情况下加载界面是否正确。我不明白什么时候需要实现整个接口,什么时候只需要调用静态方法?
    • @narocath 这更多的是针对特定场景的广泛编程问题,而不是与 Clojure 相关的任何问题。 Clojure 中的答案与 Java 中的答案相同。而且我不确定“加载界面”是什么意思。在这种情况下,不需要实现接口,因为您不会尝试提供执行特定操作以在其他地方使用的代码。就像在 Java 代码中一样,您只需要调用静态的lookupPrintServices 方法即可获得一些结果。
    猜你喜欢
    • 2017-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-06
    • 2018-07-28
    • 1970-01-01
    相关资源
    最近更新 更多