Suppose there is a Java class that doesn't provide getters and setters for all its fields, and I have to extend it with :gen-class
and fiddle with them.
How do I access the superclass fields?
The quickest (and perhaps cleanest...) solution that comes to my mind right now is to create a java class that extends my super class, and extend it instead, but I was wondering if there is an alternative that sounds more direct.
Thanks!
The methods in generated classes can access base class fields with the help of the :exposes
option of gen-class
. :exposes
expects a map where keys are symbols matching base class field names; values are also maps like {:get getterName, :set setterName}
. Clojure generates those getter and setter methods automatically. They can be used to read and modify base class fields. This is documented in the docstring for gen-class
.
This approach works for public and protected fields. It does not work for private fields.
Assuming the Java base class like this:
package fields;
class Base {
public String baseField = "base";
}
The Clojure code to generate a subclass would be:
(ns fields.core
(:gen-class
:extends fields.Base
:methods [[bar [] String]
[baz [String] Object]]
:exposes { baseField { :get getField :set setField }}))
(defn -bar [this]
(str (.getField this) "-sub"))
(defn -baz [this val]
(.setField this val)
this)
(defn -main
[& args]
(println (.. (fields.core.) (bar)))
(println (.. (fields.core.) (baz "new-base") (bar))))
Assuming all this is AOT compiled and ran, the output is:
base-sub
new-base-sub