如何将Clojure类型符号转换为java.lang.Class实例?
Convert Clojure Type Symbols (like
byte<>) to Java Classes Great question! When using clojure.reflect, array types are represented with the <> suffix on the element type symbol (like byte<> for byte[]). Here's a robust function type-symbol-to-class that handles these array symbols, plus primitive types and regular reference types:
(ns your.namespace.here (:require [clojure.reflect :as r])) (defn symbol-to-primitive-class "Convert a primitive type symbol (like 'int) to its corresponding Java Class (int.class)" [sym] (case sym 'boolean Boolean/TYPE 'byte Byte/TYPE 'char Character/TYPE 'short Short/TYPE 'int Integer/TYPE 'long Long/TYPE 'float Float/TYPE 'double Double/TYPE nil)) (defn type-symbol-to-class "Convert a type symbol from clojure.reflect (or standard type symbol) to its Java Class. Handles: - Array symbols like 'byte<> (byte[]), 'String<> (String[]) - Primitive symbols like 'int (int.class) - Regular reference type symbols like 'java.lang.String or 'java.util.List" [sym] (let [sym-name (name sym)] ;; Handle array types (denoted by <> suffix in clojure.reflect) (if (.endsWith sym-name "<>") (let [element-sym (symbol (subs sym-name 0 (- (count sym-name) 2))) ;; Resolve the element type: first check primitives, then loaded classes, then try Class/forName element-class (or (symbol-to-primitive-class element-sym) (resolve element-sym) (Class/forName (name element-sym)))] ;; Create an empty array of the element type and get its class (class (java.lang.reflect.Array/newInstance element-class 0))) ;; Handle non-array types: primitives first, then loaded classes, then Class/forName (or (symbol-to-primitive-class sym) (resolve sym) (Class/forName (name sym))))))
Testing the Function
Let's verify it works for your original case and more scenarios:
;; Your original assertion passes (assert (= (class (byte-array [1 2 3])) (type-symbol-to-class 'byte<>))) ;; Regular reference type (assert (= String (type-symbol-to-class 'java.lang.String))) ;; Primitive type (assert (= Integer/TYPE (type-symbol-to-class 'int))) ;; Reference type array (assert (= (class (make-array String 0)) (type-symbol-to-class 'String<>))) ;; Long primitive array (assert (= (class (long-array [1 2 3])) (type-symbol-to-class 'long<>))) ;; Custom class (if the class exists in your classpath) (assert (= com.example.MyClass (type-symbol-to-class 'com.example.MyClass)))
How It Works
- Primitive Type Handling: The
symbol-to-primitive-classhelper maps Clojure's primitive symbols to their corresponding JavaTYPEconstants (e.g.,'int→int.class). - Array Type Handling: We detect symbols ending with
<>(theclojure.reflectarray notation), extract the element type symbol, resolve that element's class, then create an empty array of that type to get the array class. - Fallback Resolution: For regular reference types, we first try to resolve the symbol from the current namespace, then fall back to
Class/forNameto load fully qualified class names.
内容的提问来源于stack exchange,提问作者Rulle
相关产品推荐
相关产品推荐

