использование Java перечислений или открытых статических полей в MATLAB - PullRequest
5 голосов
/ 03 августа 2009

Мне интересно, как в 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;

МАТЛАБ: ?????

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

MATLAB: ?????

Ответы [ 4 ]

12 голосов
/ 04 декабря 2009

Внутренние классы требуют преобразования '.' в $ в Matlab.

На самом деле это может быть связано с тем, как компилятор Java хранит объекты внутреннего класса. Он ведет себя аналогично для внутренних классов (например, javax.swing.plaf.basic.BasicTextUI$UpdateHandler). Matlab не такой умный, как JVM, чтобы автоматически конвертировать эти внутренние «$» в «.». Следовательно, мы не можем использовать обычные простые точечные обозначения в этих случаях в Matlab, и, поскольку «$» является недопустимым символом в синтаксисе Matlab, мы должны прибегнуть к использованию «$» в javaObject* 1006. *, javaMethod, awtinvoke и их родственников. Например:

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

Перечисления требуют аналогичного преобразования '.' в $ в Matlab. Но функция MATLAB javaObject вызывает конструктор класса, и поскольку перечисления не имеют конструктора, мы получаем следующую ошибку:

В классе Java не существует конструктора с соответствующей сигнатурой

К счастью enum имеет встроенный метод 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, вероятно, также не будет работать. Если класс со статическими методами является вложенным, вам может не повезти. Для моей утилиты systray на File Exchange я использовал подход отражения, как описано в этом посте: http://UndocumentedMatlab.com/blog/setting-system-tray-popup-messages/

Кредит: под редакцией Марк Микофски

6 голосов
/ 04 августа 2009

Вы можете ссылаться на константы перечисления Java из Matlab, используя синтаксис package.class.FIELD, как и в любом другом статическом поле Java. Допустим, у вас есть перечисление.

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

Вы можете получить константы перечисления в Matlab, используя прямую ссылку. (Конечно, классы Java должны быть в javaclasspath Matlab.)

% 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();
3 голосов
/ 03 августа 2009

EDIT: Начиная с здесь звучит так, будто обычный способ будет работать. Или Enums чем-то отличаются от других классов со статиками по какой-то причине?

Можете ли вы вызвать метод Java с параметрами?

SomeEnum e = com.example.test.SomeEnum.valueOf(SomeEnum.class, "MY_FAVORITE_ENUM")
2 голосов
/ 07 ноября 2011

Я столкнулся с той же проблемой enum, что и первая часть исходного вопроса. Собрав воедино некоторую информацию из постов, подобных этим, я понял, что использование функции javaMethod MATLAB для вызова 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 объявлен как public static int в классе Foo, я могу сделать:

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

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

Возможно, один из других ответов о знаках доллара вместе с звонками на fooVar.getClass().getFields() пролил некоторый свет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...