I also had problems with this. The example below is not elegant, but pretty simple for writing dumb little glue classes in Clojure, not in Java. Please note that all I did to ensure thread safety was to ensure that field updates were atomic - I did not use any other concurrency materials, and this can make a real difference.
The init method creates instance variables for the object. The setfield and getfield reduce atomic update accounting.
(ns #^{:doc "A simple class with instance vars" :author "David G. Durand"} com.tizra.example ) (gen-class :name com.tizra.example.Demo :state state :init init :prefix "-" :main false :methods [[setLocation [String] void] [getLocation [] String]] ) (defn -init [] "store our fields as a hash" [[] (atom {:location "default"})]) (defmacro setfield [this key value] `(swap! (.state ~this) into {~key ~value})) (defmacro getfield [this key] `(@(.state ~this) ~key)) (defn -setLocation [this ^java.lang.String loc] (setfield this :location loc)) (defn ^String -getLocation [this] (getfield this :location))
You must compile this and make sure that the stub class is produced in your classpath, and then you can instantiate, etc. like any other Java class.
=> (com.tizra.example.Demo.) #<Demo com.tizra.example.Demo@673a95af > => (def ex (com.tizra.example.Demo.))
I found a more detailed summary on this blog quite useful: http://kotka.de/blog/2010/02/gen-class_how_it_works_and_how_to_use_it.html
source share