2017-02-05 7 views
0

Ich folge this series um zu erfahren, wie clojure Compiler funktioniert.Wie StaticMethodExpr.eval aufgerufen wird?

Ich versuchte eval Methode von StaticMethodExpr mit folgenden Codes

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

aber kein Glück und IllegalArgumentException werfen aufzurufen:

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

Gibt es etwas, oder diese a bug in jdk ist?

Antwort

1

Sie können immer noch die Methode mithilfe von Reflektion nennen:

(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 

Dieses gut genug sein sollte, wenn Ihr Ziel zu entdecken.

Ein reflexionsfreie Java-Programm könnte diese Methode auf dem Ergebnis der (+ 1 2)clojure.lang.Compiler.HostExpr über eine Referenz des Typs Analyse nennen, die weder die Erklärung der Schnittstelle von clojure.lang.Compiler.Expr noch dem tatsächlichen Laufzeittyp sind öffentlich, so nehme ich an, obwohl auch öffentlich sind Es ist etwas überraschend, dass setAccessible erforderlich ist.

Verwandte Themen