【问题标题】:using Java enums or public static fields in MATLAB在 MATLAB 中使用 Java 枚举或公共静态字段
【发布时间】:2009-08-03 18:10:25
【问题描述】:

我想知道如何在 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:??????

【问题讨论】:

  • 我假设您无法编辑 Java 枚举?
  • 在某些情况下我可以,在某些情况下我不能
  • 这是类型安全枚举的另一面:我调用 loadWeirdFile('myfile.txt', Options.SKIP_WEIRD_STUFF) 没有幻数并且是类型安全的,但我无法从我的脚本环境访问 SKIP_WEIRD_STUFF 常量。 :(
  • (这不是我要调用的确切函数,但你明白了)

标签: java matlab enums


【解决方案1】:

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

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

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

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

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

幸运的是 enum has the builtin method valueOf() 可以与 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 也可能不起作用。如果具有静态方法的类是嵌套的,您可能会不走运。 对于文件交换上的系统托盘实用程序,我使用了反射方法,如本文所述:http://UndocumentedMatlab.com/blog/setting-system-tray-popup-messages/

来源:Mark Mikofski编辑

【讨论】:

  • @Yair,我是Undocumented MATLAB的忠实粉丝!感谢您进行这些编辑并给予我信任。我一直在研究JGit,它的org.eclipse.jgit.api.CreateBranchCommand 类有一个嵌套枚举SetupUpstreamMode,它的org.eclipse.jgit.lib.Constants 类有一个隐藏的构造函数,所以我遇到了这些问题。如果其他人有这些问题,最好澄清如何在 MATLAB 中提取枚举和常量。
【解决方案2】:

您可以使用 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();

【讨论】:

  • 我认为这仅在枚举未嵌套在另一个类中时才有效。如果是嵌套的,即.class里面有一个$,那么你可能需要使用this answer或者this one
【解决方案3】:

编辑: 从here 看来,常规方式就可​​以了。或者由于某种原因,枚举与其他具有静态的类不同?

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

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

【讨论】:

  • 等等:不,那行不通。我仍然需要引用 SomeEnum.class 这是一个公共静态字段。啊!
  • w/r/t 您更新的“访问私有和公共字段”链接——我想这对于在 MATLAB 中“直接”访问的字段确实有效,例如com.example.test.Myfield.FIELD_VAL,我希望我可以根据动态字符串获取它,例如fieldval = javaField('com.example.test.Myfield.FIELD_VAL') 这似乎不可能。
【解决方案4】:

我面临与原始问题的第一部分相同的枚举问题。从这里的帖子中收集一些信息,我意识到使用 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 中的普通表示法访问公共静态变量,所以我无法提供太多帮助。假设 MAX_FOO 在 Foo 类中被声明为 public static int,我可以这样做:

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-19
    相关资源
    最近更新 更多