2017-02-05 11 views
0

私はthis seriesに従って、clojureコンパイラの仕組みを学びます。StaticMethodExpr.evalを呼び出す方法は?

私はコード

(ns clojure.lang 
    (:use clojure.core) 
    (:import [clojure.lang Compiler Compiler$C])) 

(def form (read-string "(+ 1 1)")) 

(def expr (Compiler/analyze Compiler$C/EXPRESSION form)) 

(.eval expr) 

が、運の下に使用してStaticMethodExprevalメソッドを呼び出すとIllegalArgumentExceptionを投げることを試みた:

Unhandled java.lang.IllegalArgumentException 
    Can't call public method of non-public class: public 
    java.lang.Object clojure.lang.Compiler$StaticMethodExpr.eval() 

は、私が行方不明になったものありますか、これはa bug in jdkありますか?

答えて

1

あなたはまだリフレクションを使用してメソッドを呼び出すことができます。あなたの目標は探ることであるならば

(let [m (.getDeclaredMethod clojure.lang.Compiler$Expr "eval" (make-array Class 0))] 
    (.setAccessible m true) 
    (defn -eval [expr] 
    (.invoke m expr (object-array 0)))) 

(-eval (clojure.lang.Compiler/analyze clojure.lang.Compiler$C/EXPRESSION '(+ 1 2))) 
;= 3 

これは十分に良いことがあります。

無反射のJavaプログラムはclojure.lang.Compiler.Exprの宣言インタフェースも実際の実行時の型でもないが、公開されているにもかかわらず、公開されている、タイプclojure.lang.Compiler.HostExprの参照を経由して(+ 1 2)を分析した結果に、このメソッドを呼び出すことができますので、私は考えますsetAccessibleが必要であることは幾分驚くべきことです。

関連する問題