Clojure:通过代理或其他方式访问受保护的方法?

时间:2013-12-09 22:05:06

标签: java clojure

我在Clojure项目中使用SnakeYAML Java库。我想在Clojure中使用以下内容:

class DiceConstructor extends SafeConstructor {
    public DiceConstructor() {
        this.yamlConstructors.put(new Tag("!dice"), new ConstructDice());
    }

    private class ConstructDice extends AbstractConstruct {
        public Object construct(Node node) {
            String val = (String) constructScalar((ScalarNode) node);
            int position = val.indexOf('d');
            Integer a = new Integer(val.substring(0, position));
            Integer b = new Integer(val.substring(position + 1));
            return new Dice(a, b);
        }
    }
}

解释:我想创建一个SafeConstructor的子类来访问其超类的受保护字段yamlConstructors,并将AbstractConstruct的一些自定义子类添加到yamlConstructors

我正在考虑使用proxy,但似乎代理无法访问受保护的字段。还有其他可能性吗?

2 个答案:

答案 0 :(得分:1)

我最终使用clojure.contrib.reflect中的方法,如下所示:

(require '[clojure.contrib.reflect :as reflect])

(defn dice-constructor 
  "Creates a custom SafeConstructor that understands the !dice tag"
  []
  (let [result (SafeConstructor.)
        constructor (proxy [AbstractConstruct] []
                      (construct [node]
                        (let [scalar-node (cast ScalarNode node)
                              scalar (reflect/call-method BaseConstructor 'constructScalar [ScalarNode] result scalar-node)
                              string-val (cast String scalar)]
                          (println (str "Loading: " string-val)))))]
    (.put (reflect/get-field BaseConstructor 'yamlConstructors result)
          (Tag. "!dice")
          constructor)
    result))

答案 1 :(得分:0)

通常,如果你不能使用proxy因为你需要生成一个命名类,那么gen-class就是下一个选项。这需要更多的工作,并且结果更灵活。