tags:

views:

430

answers:

5

I have some matlab code and some java code that need to talk. I was getting a NoSuchMethodError When I pass a matlab double array to a java method that accepts double[] argument.

So i write a simple "hello world" to get the class of an object passed to the method

public void printArray(Object array) {

        System.out.println(array.getClass());
        System.out.println(array.getClass().getPackage());
    }

Calling this method from matlab, i get this interesting output

>> a.printArray(2)
class java.lang.Double
package java.lang
>> a.printArray('hello')
class java.lang.String
package java.lang
>> a.printArray(true)
class java.lang.Boolean
package java.lang
>> a.printArray([2 3 4])
class [D
null
>> a.printArray([true false])
class [Z
null

Can someone explain whats happening. I have matlab r14 and the java class is compiled with 1.3 compatibility

+2  A: 

Looks simple to me: Matlab passes numbers to Java as Double instances, strings as String instances, booleans as Boolean instances, and arrays as Java arrays. So try changing your method signature from method(double[] blah) to method(Double[] blah).

David Zaslavsky
I don't know if this is indeed the case... I think MATLAB passes them as primitives, and Java autoboxes them to Objects. Unfortunately, autoboxing doesn't apply to arrays. That means only method(double[] blah) would work.
Zach Scrivena
+2  A: 

MATLAB has a set of heuristics to convert MATLAB data types to the type required by the Java method being called. The full details are described in Passing Data to a Java Method in the MATLAB documentation.

The method's signature, void printArray(Object array), doesn't give MATLAB much information about what Java really wants. This is why you're seeing a variety of types, depending on how you call it.

With respect to your original question, I'm not sure why this wouldn't be working for you. Give a close look at Passing Built-In Types.

It gives the sample MATLAB code

poly = java.awt.Polygon([14 42 98 124], [55 12 -2 62], 4);

where the corresponding Java method has the signature

public Polygon(int xpoints[], int ypoints[], int npoints)

This is a little different than your question because it involves arrays of ints rather than arrays of doubles, but should work identically.

Matthew Simoneau
A: 

Apperantly java accepts the array quite fine. Its the Arrays.toString() method that fails to work on that input. I used double[] in the method signature and printed the array in a loop, and it worked. However it is still an open question as to why the strange class names apear.

Midhat
It would be great if you could incorporate your response in the original question, instead of creating a new answer.
Zach Scrivena
A: 

As others have said, it's the expected behaviour. Java arrays just don't have a very useful string representation. If you want to get a more useful string representation of your arrays, you could wrap them in a List, like:

Arrays.asList(new Double[] { 1.1, 2.2, 3.3 })
Fabian Steeg
+1  A: 

I think the original problem has been updated by the OP, so I'll take the chance to summarize our findings so far:

  • We have established that the sample code in the original question produces the expected behavior. MATLAB passes data as primitives to Java, and Java performs the appropriate autoboxing to Objects. As pointed out in matthewsim's reply, MATLAB explains how it matches its data types to Java data types in the "Passing Data to a Java Method" section of its documentation. The surprising thing is that a single MATLAB data type may match different Java data types, e.g. logical matches boolean, byte, short, int, long, float, and double, in that order of precedence.

  • The NoSuchMethodError that the OP initially encountered was caused by the use of a wrong method. This is no longer a problem. Using double[] as the method argument works.

  • The "strange" class names ([D and [Z) are actually notations used by Java to describe arrays of primitive types. The API explains the usage in Class.getName().

Case closed =)

Zach Scrivena