4

The following code

(-> (.getField (Class/forName
                "ccg.flow.processnodes.text.retrievers.Dictionary.Dictionary")
     "wordsTuples") .getType)

tells me that wordsTuples is a java.util.ArrayList. But what I would like to be able to learn is that it is an ArrayList with elements of type String[], since it happens to be declared like this:

public class Dictionary extends ProcessNode {
    public ArrayList<String[]> wordsTuples;

    public ArrayList<String> words;
...

Is there a way to obtain the "type hint" information programmatically within Clojure?

8
  • I think this IntelliJ Plugin does what you're looking for: cursiveclojure.com Commented May 28, 2015 at 14:29
  • "It will be a commercial product, with pricing to be released soon." - I'd like a generic solution. Commented May 28, 2015 at 14:32
  • I think you can use class instead of that more complicated expression to identify the object as an ArrayList. e.g. (class (java.util.ArrayList. ["a" "b" "c"])) ;=> java.util.ArrayList. Commented May 28, 2015 at 15:39
  • 1
    This question appears to be incorrectly titled. Type-hints in Clojure are there to improve performance of certain operations by hinting types to the Clojure compiler. The question's real concern appears to be about how one would obtain the generic type parameter from a generic Java collection. Perhaps asker would like to revise the title? Commented May 28, 2015 at 15:59
  • See here: stackoverflow.com/questions/1942644/… Commented May 28, 2015 at 19:51

3 Answers 3

1

No, because of type erasure. https://docs.oracle.com/javase/tutorial/java/generics/erasure.html

There is a wealth of data on your erasure on google.

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

Comments

0

You may use a simple hack based on fact which data is in your list.

E.g. you have got some list of strings:

(def lst (java.util.ArrayList. ["my" "list" "of" "strings"]))

Then you can get type of item:

(if (and (instance? java.util.List lst) 
         (not (.isEmpty lst))) 
   (.getName (.getClass (.get lst 0))))

Drawback of this workaround is that you cannot get reflection info about empty list b/c of erasure mentioned by freakhill, but who cares about empty lists ;)?

Hope this helps.

Comments

0

Thanks to the comments, I found this answer on the question Get generic type of java.util.List. And from there, a simple modification of my sample code now works as desired:

(-> (.getField (Class/forName
             "ccg.flow.processnodes.text.retrievers.Dictionary.Dictionary")
     "wordsTuples") .getGenericType)

Returns:

#<ParameterizedTypeImpl java.util.ArrayList<java.lang.String[]>>

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.