我正在尝试使用 GWT 的 JSNI 通过 native 代码调用 Java 函数。 Java 函数中有一个枚举,我很好奇该枚举是否会按照我想要的方式进行编码。我在 Google 或 SO 上找不到任何有用的东西,并且 the Google basic docs不是很具体。我确信我会在编译和运行时找到答案,但我想我不妨问一下。
给出像这样大大简化的代码:
package my.example.package;
public class Giant {
public enum GiantWord { FEE, FIE, FO, FUM };
public void sayGiantWord(GiantWord word) { /* ... */ }
public native JavaScriptObject toJS() /*-{
var Giant = function() {
this.sayGiantWord = function(word) {
this.@my.example.package::sayGiantWord(Lmy/example/package/Giant$GiantWord;)(word);
};
};
return new Giant();
}-*/;
}
编辑 - 根据评论,让我给出 toJS 函数的替代版本,并避免 this
和 this 之间发生混淆。
public static native JavaScriptObject toJS(final Giant g) /*-{
var Giant = function() {
this.sayGiantWord = function(word) {
g.@my.example.package::sayGiantWord(Lmy/example/package/Giant$GiantWord;)(word);
};
};
return new Giant();
}-*/;
从 JavaScript 中调用 sayGiantWord("FEE")
(在从 toJS()
中适当获取的 var 上)可以正常工作吗?换句话说,JSNI 编码器能否正确地将 String 转换为其匹配的 Java 枚举?
我希望调用 sayGiantWord(1)
更容易正确编码,因为 int 可以轻松转换为枚举。
其他说明:
- GWT Eclipse 插件为我提供了访问类成员枚举的语法。至少到目前为止,GWT 正在与我合作。
- 我不想传递数字,如果有必要,我知道我可以使用 Java 类中的转换函数处理字符串,如下所示;我只是不想这样做。
public void sayGiantWordJS(String word) {
// convert the string to an enum
// call sayGiantWord
}
感谢您的建议!
最佳答案
JSNI 无法处理 Java 枚举,但您可以将枚举字符串传递到 JSNI 层,以及将从 JSNI 方法返回的字符串转换回枚举。
您最好单独表示 Giant
JavaScript 对象,并从 Giant
Java 类型委托(delegate)给 JSNI 层。这样您就可以保持关注点分离并松散地耦合实现和抽象:
public class GiantJso extends JavaScriptObject {
protected GiantJso() {
}
public static final native GiantJso create(String wordA, String wordB,
String wordC) /*-{
return {
vocabulary : [ wordA, wordB, wordC ],
said : ''
};
}-*/;
public final native void sayGiantWord(String word) /*-{
if (this.vocabulary.indexOf(word) != -1) {
console.log("i'm a giant, here me roar: ", word, "!");
this.said = word;
}
}-*/;
public final native JsArrayString vocabulary() /*-{
return this.vocabulary || null;
}-*/;
public final native String said() /*-{
return this.said;
}-*/;
}
然后将其包装在 Java 类型中:
public class Giant {
private GiantJso jso;
public Giant() {
jso = GiantJso.create(GiantWord.FEE.name(),
GiantWord.FEE.name(), GiantWord.FEE.name());
}
public void sayGiantWord(GiantWord word) {
jso.sayGiantWord(word.name());
}
public GiantWord getSaidWord() {
return GiantWord.valueOf(jso.said());
}
}
vocabulary
和 said
只是可以分配给 JSO 的其他属性的示例,当然,您可以自由地实现您希望的任何结构。
进一步阅读
- JSNI overlay types GWT 文档开发指南。
注意:如果您想要将 Java 类表示为 JavaScript 构造,请查看 GWT exporter .
关于java - JSNI Marshal Enum 可以作为字符串吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14963306/