Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

using Java enums or public static fields in MATLAB

Tags:

java

enums

matlab

I'm wondering how in MATLAB you can get a reference to a Java enum or static public field. In MATLAB, if you are trying to use Java objects/methods, there are equivalents to Java object creation / method call / etc.:

Java: new com.example.test.Foo();

MATLAB: javaObject('com.example.test.Foo');

Java: com.example.test.Foo.staticMethod();

MATLAB: javaMethod('staticMethod', 'com.example.test.Foo');

Java: SomeEnum e = com.example.test.SomeEnum.MY_FAVORITE_ENUM;

MATLAB: ?????

Java: int n = com.example.test.Foo.MAX_FOO;

MATLAB: ?????

like image 217
Jason S Avatar asked Aug 03 '09 18:08

Jason S


People also ask

Should enums be public or private?

Enum Fields When the constant enum values are defined, an int value is passed to the enum constructor. The enum constructor must be private . You cannot use public or protected constructors for a Java enum .

Why we should not use enum in Java?

If you ever need to change the value of a String constant, it is a one-line change. With an enum it can get more complicated due to having separate values for name and toString, and those values possibly being used in conditional logic.

Can Java enum have static fields?

Thus for enums its always guaranteed that static fields wont be initialized before enum constants. Since we cannot give any sensible values to static fields for use in enum constructor, it would be meaningless to access them in enum constructor.

Why enums are better than strings?

The advantage of an enum is that they are a strongly typed value. There are no advantages to using strings.


2 Answers

Inner classes require conversion of '.' to '$' in Matlab.

This may actually due to the way the Java compiler stores internal class objects. It behaves similarly for internal classes (e.g. javax.swing.plaf.basic.BasicTextUI$UpdateHandler). Matlab is not as smart as the JVM to automatically convert these internal '$' into '.'. Therefore, we can't use the regular simple dot-notation in these cases in Matlab, and since '$' is an invalid character in Matlab syntax, we must resort to using the '$' within javaObject, javaMethod, awtinvoke and their relatives. For example:

Java: InnerClass c = new com.example.test.SomeEnum.InnerClass;
MATLAB: c = javaObject('com.example.test.SomeEnum$InnerClass')

Enums require similar conversion of '.' to '$' in Matlab. But MATLAB's javaObject function calls the class constructor, and since enums have no constructor, we get the following error:

No constructor with appropriate signature exists in Java class

Luckily enum has the builtin method valueOf() that we can use with javaMethod:

Java: SomeEnum e = com.example.test.SomeEnum.MY_FAVORITE_ENUM;
MATLAB: e = javaMethod('valueOf','com.example.test$SomeEnum','MY_FAVORITE_ENUM');

Similarly:

Java: int n = com.example.test.Foo.MAX_FOO;
MATLAB: n = javaMethod('com.example.test.Foo$MAX_FOO')

Static fields can be gotten directly in Matlab using simple dot notation:

redColor = java.awt.Color.red;

The full list of static fields can be gotten using Matlab's built-in struct function:

>> staticFields = struct(java.awt.Color.red)
staticFields = 
      white: [1x1 java.awt.Color]
      WHITE: [1x1 java.awt.Color]
  lightGray: [1x1 java.awt.Color]
 LIGHT_GRAY: [1x1 java.awt.Color]
       gray: [1x1 java.awt.Color]
       GRAY: [1x1 java.awt.Color]
   darkGray: [1x1 java.awt.Color]
  DARK_GRAY: [1x1 java.awt.Color]
      black: [1x1 java.awt.Color]
      BLACK: [1x1 java.awt.Color]
        red: [1x1 java.awt.Color]
        RED: [1x1 java.awt.Color]
       pink: [1x1 java.awt.Color]
       PINK: [1x1 java.awt.Color]
     orange: [1x1 java.awt.Color]
     ORANGE: [1x1 java.awt.Color]
     yellow: [1x1 java.awt.Color]
     YELLOW: [1x1 java.awt.Color]
      green: [1x1 java.awt.Color]
      GREEN: [1x1 java.awt.Color]
    magenta: [1x1 java.awt.Color]
    MAGENTA: [1x1 java.awt.Color]
       cyan: [1x1 java.awt.Color]
       CYAN: [1x1 java.awt.Color]
       blue: [1x1 java.awt.Color]
       BLUE: [1x1 java.awt.Color]
     OPAQUE: 1
    BITMASK: 2
TRANSLUCENT: 3

MATLAB's function javaObject may not work if the default constructor is private (hidden), and javaMethod probably won't work either. If the class with the static methods is nested you may be out of luck. For my systray utility on the File Exchange, I used the reflection approach, as described in this post: http://UndocumentedMatlab.com/blog/setting-system-tray-popup-messages/

Credit: edited by Mark Mikofski

like image 59
Yair Altman Avatar answered Oct 05 '22 12:10

Yair Altman


You can reference Java enum constants from Matlab using the package.class.FIELD syntax, as with any other static Java field. Let's say you have an enum.

package com.example;
public enum MyEnum {
    FOO, BAR, BAZ
}

You can get at the enum constants in Matlab using a direct reference. (The Java classes must be in Matlab's javaclasspath, of course.)

% Static reference
foo = com.example.MyEnum.FOO

% Import it if you want to omit the package name
import com.example.MyEnum;
foo = MyEnum.FOO
bar = MyEnum.BAR

If you want a "dynamic" reference determined at runtime, you can just build a string containing the equivalent static reference and pass it to eval(). This works on almost any Matlab code.

% Dynamic reference
foo = eval('com.example.MyEnum.FOO')

And if you want to get really fancy, you can use Java reflection to get at all the enumerated constants at run time. Make a thin wrapper to put with your other custom classes to get around quirks with Matlab's classloader. (There's no Matlab javaClass() equivalent; IMHO this is a Matlab oversight.)

//In Java
package com.example;
public class Reflector {
    public static Class forName(String className) throws Exception {
        return Class.forName(className);
    }
}

Then you can enumerate the constants in Matlab.

% Constant enumeration using reflection
klass = com.example.Reflector.forName('com.example.MyEnum');
enums = klass.getEnumConstants();
like image 36
Andrew Janke Avatar answered Oct 05 '22 12:10

Andrew Janke