6

I'm having a play with the Java NIO.2 API from JDK 7.

In particular, I want to call the method: Paths#get(String first, String... more)

This is a static method which takes in at least one string, and returns a Path object corresponding to it. There's an overloaded form: Paths#get(URI uri)

However, I can't seem to call the top method from Clojure. The nearest I can seem to get is this:

(Paths/get ^String dir-fq (object-array 0))

which fails with:

java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;

as you might expect. After all, we're passing in an Object[] to something that's expecting String[].

I've tried removing the (object-array) form - but that just causes Clojure to try to call the get(URI) method - both with and without the type hint.

Passing nil as the second argument to Paths#get(String, String...) causes the right method to be called, but Java 7 then fails with an NPE.

I can't seem to find a way in Clojure to express the type String[] - I'm guessing I either need to do that or provide a hint to the dispatch system.

Any ideas?

1 Answer 1

15

As you noticed, it doesn't want an Object[], it wants a String[]. object-array does exactly what it says: it makes an array of objects. If you want to create an array with some different type, make-array and into-array are your friends. For example here:

(Paths/get "foo" (into-array String ["bar" "baz"]))

The String specifier there is optional in this case: if you leave out the array's desired type, Clojure uses the type of the first object as the array's component type.

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

2 Comments

Cool. Any idea why just passing a single String parameter causes the runtime to attempt to call the Paths#get(URI) method and coerce the String into a URI?
If there's only one one-argument get method, this wouldn't surprise me. At the bytecode level, as I think you're aware, the vararg version is just a two-arg version taking String, String[]. If you only pass one object, the compiler might say "well there's only one one-arg version, so I'll call that and hope for the best instead of wasting time on reflection to see if it matches".

Your Answer

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