liveBook · Manning

Clojure proxy

As explained in Clojure: The Essential Reference

proxy is a Clojure facility that generates a Java class extending a concrete class or implementing interfaces and returns instances with method overrides.

Clojure's proxy facility creates a Java class, extends a concrete class or implements interfaces, and immediately returns an instance with functional method overrides. It targets interoperability cases where a Java framework requires inheritance, while capturing surrounding lexical bindings for use in implementations. section 15.5 section 15.0

A proxy combines several operations that can also be controlled separately:

  • Pass parent classes and interfaces, constructor arguments, and method-override forms to proxy. section 15.5
  • Reuse generated proxy classes when proxies share a signature, while keeping each instance's overridden methods and closed-over variables separate. section 15.5
  • Inspect or replace implementations after creation with proxy-mappings or update-proxy. section 15.5
  • Separate class generation, construction, and initialization with get-proxy-class, construct-proxy, and init-proxy when lifecycle control matters. section 15.5

Extending java.io.File

(defn cfile [fname] (proxy [File Concatenable] [^String fname] (concat [^File f] (spit (.getPath f) (slurp this) :append true) f))) (def etchosts (cfile "/etc/hosts")) (.concat etchosts f2) The proxy adds concatenation behavior to a File-compatible object without changing the existing interface. update-proxy can later replace concat, for example to create the destination file automatically. section 15.5

Separating proxy lifecycle phases

(def DocumentException (get-proxy-class Exception IDeref)) (-> DocumentException (construct-proxy "message") (init-proxy {"deref" (fn [this] "Cause: message")})) get-proxy-class can prepare reusable classes, construct-proxy selects constructor arguments, and init-proxy installs method overrides. section 15.5

(def ^Runnable r ; #1
  (proxy [Runnable] [] ; #2
    (run [] (println (rand))))) ; #3

(.run r) ; #4
;; 0.1678203879530764

A minimal Runnable proxy shows the target interface, empty constructor arguments, overridden run method, and immediate invocation. section 15.5

How Clojure: The Essential Reference covers it

How deep it goes
Explains generation, closures, caching, runtime updates, and separated lifecycle phases, but defers broader polymorphic dispatch to related facilities.
Examples
Uses Runnable, java.io.File concatenation, runtime override replacement, and reusable exception proxy classes.
What it assumes
Assumes Java class and interface concepts while demonstrating Clojure functions, closures, constructor arguments, and method overrides.
What you can do after
Build Java-compatible objects with overridden methods, alter implementations, or control proxy generation and construction separately.
How it connects
Connects proxy with gen-class, reify, get-proxy-class, construct-proxy, init-proxy, update-proxy, protocols, and multimethods.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Clojure: The Essential Reference. The section links point to the parts of the book it draws on.