Documentation |
On this page… |
---|
Conversion of MATLAB Argument Data |
When you call a Java^{®} method, MATLAB^{®} types you pass in the call are converted to types native to the Java language. MATLAB performs this conversion on each argument that is passed, except for those arguments that are already Java objects. This section describes the conversion that is performed on specific MATLAB types and, at the end, also looks at how argument types affect calls made to overloaded methods.
If the method returns data, MATLAB converts the data to the appropriate MATLAB format. This process is covered in Handling Data Returned from Java Methods.
MATLAB converts MATLAB data, passed as arguments to Java methods, into types that best represent the data to the Java language. The following table shows all of the MATLAB base types for passed arguments and the Java types defined for the parameters. Each row shows a MATLAB type followed by the possible Java argument matches, from left to right in order of closeness of the match. The MATLAB types (except cell arrays) can all be scalar (1-by-1) arrays or matrices. All of the Java types can be scalar values or arrays.
Conversion of MATLAB Types to Java Types
MATLAB Argument | Java Parameter Type (Scalar or Array) | ||||||
---|---|---|---|---|---|---|---|
Closest Type <———————————————————————> Least Close Type | |||||||
logical | boolean | byte | short | int | long | float | double |
double | double | float | long | int | short | byte | boolean |
single | float | double | |||||
char (1-by-1 scalar) | String | char | |||||
char (1-by-n or n-by-1, n>1) | String | char[] | |||||
char(m-by-n, m,n>1) | String[] | ||||||
uint8 | byte | short | int | long | float | double | |
uint16 | short | int | long | float | double | ||
uint32 | int | long | float | double | |||
uint64 | long | float | double | ||||
cell array of strings | String[] | ||||||
Java object | Object | ||||||
cell array of object | Object[] | ||||||
MATLAB object | Unsupported |
For more information about type conversion of arguments passed to Java code, see:
The Java language has eight types that are intrinsic to the language and are not represented as Java objects. These are often referred to as built in, or elemental, types and they include boolean, byte, short, long, int, double, float, and char. MATLAB converts its own types to these Java built-in types according to the table, Conversion of MATLAB Types to Java Types. Built-in types are in the first ten rows of the table.
When a Java method you are calling expects one of these types, you can pass it the type of MATLAB argument shown in the leftmost column of the table. If the method takes an array of one of these types, you can pass a MATLAB array of the type. MATLAB converts the type of the argument to the type assigned in the method declaration.
The following MATLAB code creates a top-level window frame and sets its dimensions. The call to setBounds passes four MATLAB scalars of the double type to the inherited Java Frame method, setBounds, that takes four arguments of the int type. MATLAB converts each 64-bit double type to a 32-bit integer before calling the method.
The setBounds method declaration:
public void setBounds(int x, int y, int width, int height)
The MATLAB code that calls the method:
frame = java.awt.Frame; setBounds(frame,200,200,800,400) setVisible(frame,1)
To call a Java method with an argument defined as an array of a built-in type, you can create and pass a MATLAB matrix with a compatible base type. The following code defines a polygon by sending four x and y coordinates to the Polygon constructor. Two 1-by-4 MATLAB arrays of double are passed to java.awt.Polygon, which expects integer arrays in the first two arguments. Shown here is the Java method declaration followed by MATLAB code that calls the method, and then verifies the set coordinates.
public Polygon(int xpoints[], int ypoints[], int npoints) poly = java.awt.Polygon([14 42 98 124], [55 12 -2 62], 4); [poly.xpoints poly.ypoints] % Verify the coordinates ans = 14 55 42 12 98 -2 124 62
Since MATLAB arrays are passed by value, any changes that a Java method makes to them are not visible to your MATLAB code. If you need to access changes that a Java method makes to an array, then, rather than passing a MATLAB array, you should create and pass a Java array, which is a reference. For a description of using Java arrays in MATLAB, see Working with Java Arrays.
When passing an integer type to a Java method that takes a Java integer parameter, the MATLAB conversion is the same as the Java conversion between integer types. In particular, if the integer is out-of-range (does not fit into the number of bits of the parameter type), MATLAB discards all lowest n bits, where n is the number of bits in the parameter type. This is unlike conversion between MATLAB integer types, where out-of-range integers are converted to the maximum or minimum value that can be represented by the destination type.
If the argument is floating point, MATLAB does not convert to an integer in the same manner as Java. A floating point number is first converted to a 64-bit signed integer with the fractional part truncated and then processed as if it were an int64 argument.
When a floating point number is too large to be represented in a 64-bit integer (outside the range from -2^{63}–2^{63}), MATLAB converts the value as follows:
Convert int, short, and byte parameter values to 0.
Convert long parameter values to java.lang.Long.MIN_VALUE.
Convert Inf and -Inf values to -1.
Convert NaN values to 0.
To call a Java method that has an argument defined as an object of class java.lang.String, you can pass either a String object that was returned from an earlier Java call or a MATLAB 1-by-n character array. If you pass the character array, MATLAB converts the array to a Java object of java.lang.String for you.
For a programming example, see Read URL. This example shows a MATLAB character array that holds a URL being passed to the Java URL class constructor. The following constructor expects a Java String argument.
public URL(String spec) throws MalformedURLException
In the MATLAB call to this constructor, a character array specifying the URL is passed. MATLAB converts this array to a Java String object before calling the constructor.
url = java.net.URL('http://archive.ncsa.uiuc.edu/demoweb/')
When the method you are calling expects an argument of an array of type String, you can create such an array by packaging the strings together in a MATLAB cell array. The strings can be of varying lengths since you are storing them in different cells of the array. As part of the method call, MATLAB converts the cell array to a Java array of String objects.
In the following example, the echoPrompts method of a user-written class accepts a string array argument that MATLAB converted from its original format as a cell array of strings. The parameter list in the Java method appears as follows:
public String[] echoPrompts(String s[])
You create the input argument by storing both strings in a MATLAB cell array. MATLAB converts this structure to a Java array of String.
myaccount.echoPrompts({'Username: ','Password: '}) ans = 'Username: ' 'Password: '
When calling a method that has a parameter belonging to a Java class (other than java.lang.Object), you must pass a Java object that is an instance of that class. MATLAB does not automatically convert MATLAB types to Java Object types. Unlike Java, MATLAB does not do autoboxing for numbers, such as converting double to Double.
In the example below, the add method belonging to the java.awt.Menu class requires, as an argument, an object of the java.awt.MenuItem class. The method declaration is:
public MenuItem add(MenuItem mi)
The example operates on the frame created in the previous example in Passing Built-In Types. The second, third, and fourth lines of code shown here add items to a menu to be attached to the existing window frame. In each of these calls to menu1.add, an object that is an instance of the java.awt.MenuItem Java class is passed.
menu1 = java.awt.Menu('File Options'); menu1.add(java.awt.MenuItem('New')); menu1.add(java.awt.MenuItem('Open')); menu1.add(java.awt.MenuItem('Save')); menuBar=java.awt.MenuBar; menuBar.add(menu1); frame.setMenuBar(menuBar);
A special case exists when the method being called takes an argument of the java.lang.Object class. Since this class is the root of the Java class hierarchy, you can pass objects of any class in the argument. When passing a MATLAB argument, the argument is automatically converted to the closest Java Object type, which might include Java-style autoboxing, as shown in the following table.
MATLAB Argument | Java Object |
---|---|
logical | Boolean |
double | Double |
single | Float |
char (1-by-1 scalar) | Character |
char (1-by-n or n-by-1, n>1) | String |
uint8 | Byte |
uint16 | Short |
uint32 | Integer |
uint64 | Long |
cell array of strings | String[] |
Java object | Object |
cell array of object | Object[] |
MATLAB object | Unsupported |
The only types of object arrays that you can pass to Java methods are Java arrays and MATLAB cell arrays. MATLAB automatically converts the cell array elements to java.lang.Object class objects. In order for a cell array to be passed from MATLAB, the corresponding argument in the Java method signature must specify java.lang.Object or an array of java.lang.Object.
If the objects are already in a Java array, either an array returned from a Java constructor or constructed in MATLAB by the javaArray function, then you simply pass it as the argument to the method being called. MATLAB does not convert the argument, because the argument is already a Java array.
The following example shows the mapPoints method of a user-written class accepting an array of java.awt.Point objects. The declaration for this method is:
public Object mapPoints(java.awt.Point p[])
The following MATLAB code creates a 4-by-1 array containing four Java Point objects. When the array is passed to the mapPoints method, no conversion is necessary because the javaArray function created a Java array of java.awt.Point objects.
pointObj = javaArray('java.awt.Point',4); pointObj(1) = java.awt.Point(25,143); pointObj(2) = java.awt.Point(31,147); pointObj(3) = java.awt.Point(49,151); pointObj(4) = java.awt.Point(52,176); testData.mapPoints(pointObj);
You create a cell array of Java objects by using the MATLAB syntax {a1,a2,...}. You index into a cell array of Java objects in the usual way, with the syntax a{m,n,...}.
The following example creates a cell array of two Frame objects, frame1 and frame2, and assigns it to variable frameArray.
frame1 = java.awt.Frame('Frame A'); frame2 = java.awt.Frame('Frame B'); frameArray = {frame1, frame2}
frameArray = [1x1 java.awt.Frame] [1x1 java.awt.Frame]
The next statement assigns element {1,2} of the cell array frameArray to variable f.
f = frameArray {1,2}
f = java.awt.Frame[frame2,0,0,0x0,invalid,hidden,layout = java.awt.BorderLayout,resizable,title=Frame B]
There are several remaining items of interest regarding the way MATLAB converts its data to a compatible Java type. This includes how MATLAB matches array dimensions, and how it handles empty matrices and empty strings.
The term dimension refers to the number of subscripts required to address the elements of an array. For example, a 5-by-1 array has one dimension, because you can index individual elements using only one array subscript.
In converting MATLAB to Java arrays, MATLAB handles dimension in a special manner. For a MATLAB array, dimension can be considered as the number of nonsingleton dimensions in the array. For example, a 10-by-1 array has dimension 1, and a 1-by-1 array has dimension 0. In Java code, dimension is determined solely by the number of nested arrays. For example, double[][] has dimension 2, and double has dimension 0.
If the number of dimensions of the Java array exactly matches the MATLAB array's number of dimensions n, the conversion results in a Java array with n dimensions. If the Java array has fewer than n dimensions, the conversion drops singleton dimensions, starting with the first one, until the number of remaining dimensions matches the number of dimensions in the Java array.
The empty matrix is compatible with any method argument for which NULL is a valid value in the Java language. The empty string ('') in MATLAB translates into an empty (not NULL) String object in Java code.
When you invoke an overloaded method on a Java object, MATLAB determines which method to invoke by comparing the arguments your call passes to the arguments defined for the methods. In this discussion, the term method includes constructors. When it determines the method to call, MATLAB converts the calling arguments to Java method types according to Java conversion rules, except for conversions involving objects or cell arrays. See Passing Objects in an Array.
When your MATLAB function calls a Java method, MATLAB:
Checks to make sure that the object (or class, for a static method) has a method by that name.
Determines whether the invocation passes the same number of arguments of at least one method with that name.
Makes sure that each passed argument can be converted to the Java type defined for the method.
If all of the preceding conditions are satisfied, MATLAB calls the method.
In a call to an overloaded method, if there is more than one candidate, MATLAB selects the one with arguments that best fit the calling arguments. First, MATLAB rejects all methods that have any argument types that are incompatible with the passed arguments (for example, if the method has a double argument and the passed argument is a char type).
Among the remaining methods, MATLAB selects the one with the highest fitness value, which is the sum of the fitness values of all its arguments. The fitness value for each argument is the fitness of the base type minus the difference between the MATLAB array dimension and the Java array dimension. (Array dimensionality is explained in How Array Dimensions Affect Conversion.) If two methods have the same fitness, the first one defined in the Java class is chosen.
Suppose that a function constructs a java.io.OutputStreamWriter object, osw, and then invokes a method on the object.
osw.write('Test data', 0, 9);
MATLAB finds that the class java.io.OutputStreamWriter defines three write methods.
public void write(int c); public void write(char[] cbuf, int off, int len); public void write(String str, int off, int len);
MATLAB rejects the first write method, because it takes only one argument. Then, MATLAB assesses the fitness of the remaining two write methods. These differ only in their first argument, as explained below.
In the first of these two write methods, the first argument is defined with base type, char. The table, Conversion of MATLAB Types to Java Types, shows that for the type of the calling argument (MATLAB char), Java type, char, has a value of 6. There is no difference between the dimension of the calling argument and the Java argument. So the fitness value for the first argument is 6.
In the other write method, the first argument has Java type String, which has a fitness value of 7. The dimension of the Java argument is 0, so the difference between it and the calling argument dimension is 1. Therefore, the fitness value for the first argument is 6.
Because the fitness value of those two write methods is equal, MATLAB calls the one listed first in the class definition, with char[] first argument.