在MATLAB中使用Java枚举或公共静态字段

时间:2009-08-03 18:10:25

标签: java matlab enums

我想知道如何在MATLAB中获得对Java enum或静态公共字段的引用。在MATLAB中,如果您尝试使用Java对象/方法,则可以使用Java对象创建/方法调用/等等。

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:?????

4 个答案:

答案 0 :(得分:12)

内部类需要转换'。'到Matlab中的'$'。

这实际上可能是由于Java编译器存储内部类对象的方式。对于内部类(例如javax.swing.plaf.basic.BasicTextUI$UpdateHandler),它的行为类似。 Matlab并不像JVM那样聪明,可以将这些内部'$'自动转换为'。'。因此,在Matlab中我们不能在这些情况下使用常规的简单点符号,并且由于'$'在Matlab语法中是无效字符,我们必须求助于javaObject中的'$',{{ 3}},awtinvoke及其亲属。例如:

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

枚举需要类似的'。'转换。到Matlab中的'$'。但MATLAB的javaObject函数调用类构造函数,由于枚举没有构造函数,我们得到以下错误:

  

Java类

中不存在具有适当签名的构造函数

幸运的是javaMethod我们可以使用javaMethod

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

类似地:

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

可以使用简单的点符号在Matlab中直接获取静态字段:

redColor = java.awt.Color.red;

可以使用Matlab的内置struct函数获取静态字段的完整列表:

>> 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的函数javaObject可能不起作用,而javaMethod可能也不起作用。如果嵌套静态方法的类可能会运气不好。 对于我在文件交换中的systray实用程序,我使用了反射方法,如本文所述:enum has the builtin method valueOf()

信用:由http://UndocumentedMatlab.com/blog/setting-system-tray-popup-messages/

编辑

答案 1 :(得分:6)

您可以使用package.class.FIELD语法从Matlab引用Java枚举常量,就像使用任何其他静态Java字段一样。假设你有一个枚举。

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

您可以使用直接引用获取Matlab中的枚举常量。 (当然,Java类必须在Matlab的javaclasspath中。)

% 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

如果要在运行时确定“动态”引用,可以只构建包含等效静态引用的字符串并将其传递给eval()。这适用于几乎所有Matlab代码。

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

如果你想变得非常花哨,你可以使用Java反射在运行时获取所有枚举常量。使用其他自定义类创建一个瘦的包装器,以便使用Matlab的类加载器来解决问题。 (没有Matlab javaClass()等价;恕我直言这是Matlab的疏忽。)

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

然后你可以在Matlab中枚举常量。

% Constant enumeration using reflection
klass = com.example.Reflector.forName('com.example.MyEnum');
enums = klass.getEnumConstants();

答案 2 :(得分:3)

编辑: 从here开始,听起来就像常规方式一样。或者由于某种原因,Enums与其他具有静态的类不同?

你能用参数调用Java方法吗?

SomeEnum e = com.example.test.SomeEnum.valueOf(SomeEnum.class, "MY_FAVORITE_ENUM")

答案 3 :(得分:2)

我面临与原始问题的第一部分相同的枚举问题。将这些信息放在这里的帖子中,我意识到使用MATLAB的javaMethod函数来调用valueOf()有效:

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

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

至于第二个问题,关于静态变量,我已经能够使用MATLAB 2009b中的常规符号访问公共静态变量,所以我在那里得不到多少帮助。假设在Foo类中将MAX_FOO声明为公共静态int,我可以这样做:

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

MATLAB:n = com.example.test.Foo.MAX_FOO;

也许关于美元符号的其他答案之一以及对fooVar.getClass().getFields()的调用将会有所启发。