Как использовать Java varargs с собственным интерфейсом GWT Javascript? (иначе, «GWT не имеет printf ()») - PullRequest
5 голосов
/ 23 февраля 2011

Я пытаюсь быстро освоить GWT как часть нового проекта.Я обнаружил, что GWT не реализует функцию Java String.format (), поэтому нет функции, аналогичной printf ().Я знал, что для Javascript существуют некоторые реализации printf (), поэтому я решил, что могу вставить одну из них в качестве функции GWT Javascript Native Interface.Я столкнулся с проблемами и решил, что лучше убедиться, что значения varargs передаются правильно.Вот где все стало ужасно.Сначала приведем пример кода:

// From Java, call the JSNI function:
test("sourceString", "params1", "params2", "params3");

....

public static native void test(Object... params) /*-{   
    // PROBLEM: this kills GWT!
    // alert(params.length);  

    // returns "function"
    alert(typeof(params));      

    // returns "[Ljava.lang.Object;@b97ff1"
    alert(params);
}-*/;

В документации GWT говорится, что «вызов метода JavaScript varargs из Java приведет к тому, что вызываемый объект получит аргументы в массиве».Я подумал, что это значит, что я мог бы по крайней мере проверить params.length, но при доступе к нему выбрасывается исключение JavascriptException, заключенное в исключение UmbrellaException, без реальной информации.Когда я делаю "typeof (params)", он возвращает "функцию".Как будто это не достаточно странно, если я проверяю строковое значение params, он возвращает то, что выглядит как строковая версия ссылки на Java.

Итак, я предполагаю, что задаю несколько разных вопросовздесь:

1) Как на самом деле работают GWT / JSNI varargs, и нужно ли делать что-то особенное для передачи значений?
2) Что на самом деле здесь происходит?
3)Есть ли более простой способ получить форматирование в стиле printf () в GWT-приложении?

1 Ответ

5 голосов
/ 23 февраля 2011

Ваш метод JSNI получает аргументы, но, к сожалению, ничего не может с ними сделать. Java-массивы (varargs реализуются путем создания массивов переданных аргументов) непрозрачны при передаче в методы JSNI. Однако вы можете достичь своей цели с помощью JsArrayString :

public static native void test(JsArrayString strings) /*-{
  // strings is a normal JavaScript array of strings
}

И вызов метода:

String[] jStrings = {"one", "two", "three"};
JsArrayString jsStrings = (JsArrayString)JsArrayString.createArray();

for (String s : jStrings) {
  jsStrings.push(s);
}

test(jsStrings);
...