9

I'm a novice in clojure and java.

In order to access a Java field in Clojure you can do:

Classname/staticField

which is just the same as

(. Classname staticField)

(correct me if I'm wrong)

How can I access a static field when the name of the field in held within a variable? i.e.:

(let [key-stroke 'VK_L
      key-event KeyEvent/key-stroke])

I want key-stroke to be evaluated into the symbol VK_L before it tries to access the field.

2
  • 3
    In addition to skuro's answer, you can look at the Java reflection API. See the "Changing Values of Fields" section at java.sun.com/developer/technicalArticles/ALT/Reflection . Commented Jul 8, 2011 at 23:04
  • To explaing a bit more: Access of fields or method calls have to be compiled in the byte code. That's why you can't construct them with runtime information. If you need that, you'll have to use reflection. (see Joost's answer) Commented Jul 11, 2011 at 7:07

4 Answers 4

10

In this case you might want to do something like the following:

user=> (def m 'parseInt)          
#'user/m
user=> `(. Integer ~m "10")       
(. java.lang.Integer parseInt "10")
user=> (eval `(. Integer ~m "10"))
10

If you feel like it's a bit hack-ish, it's because it really is such. There might be better ways to structure the code, but at least this should work.

Sign up to request clarification or add additional context in comments.

1 Comment

Did this answer help you? Care to accept it (or anyone else's)?
7

I made a small clojure library that translates public fields to clojure maps using the reflection API:

(ns your.namespace
 (:use nl.zeekat.java.fields))

(deftype TestType
    [field1 field2])

; fully dynamic:

(fields (TestType. 1 2)) 
=> {:field1 1 :field2 2}

; optimized for specific class:
(def-fields rec-map TestType)

(rec-map (TestType. 1 2)) 
=> {:field1 1 :field2 2}

See https://github.com/joodie/clj-java-fields

Comments

5

Reflection is probably the proper route to take, but the easiest way is

(eval (read-string (str "KeyEvent/" key-stroke)))

This will just convert the generated string into valid clojure and then evaluate it.

Comments

1

You can construct the right call as an s-expression and evaluate it as follows:

(let [key-stroke 'VK_L
      key-event (eval `(. KeyEvent ~key-stroke))]
  ....do things with your key-event......)

However, if what you are trying to do is test whether a particular key has been pressed, you may not need any of this: I usually find that it is easiest to write code something like:

(cond
  (= KeyEvent/VK_L key-value) 
    "Handle L"
  (= KeyEvent/VK_M key-value) 
    "Handle M"
  :else
    "Handle some other key")

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.