3
votes

There's something I'm not getting about Java interop. I have a single character java.lang.String "x". Java Strings have a getBytes method whose signature is public byte[] getBytes(String charsetName) throws UnsupportedEncodingException: https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#getBytes(java.lang.String.

That method returns a byte[]. Java arrays have a property .length. Why do I get an IllegalArgumentException in the REPL?

(.length (.getBytes "x" "UTF-8"))
IllegalArgumentException No matching field found: length for class [B  clojure.lang.Reflector.getInstanceField (Reflector.java:271)

How do I correctly get the length of the byte array returned by (.getBytes "x" "UTF-8") in clojure?

1

1 Answers

10
votes

There is the alength function in clojure.core to get the length of Java arrays

(alength (.getBytes "x" "UTF-8"))
;;=> 1

As far as I know, Java arrays are not really classes with a field called length, even though Java syntax myarray.length suggests otherwise. Getting the length of an array requires a special byte code instruction, not the typical field access. That's why the field access interop syntax in Clojure in this case results in an exception. And for the same reason a special purpose alength function is required.