我在GWT中具有以下实体
@JsType(namespace = "my.entities")
public class MyEntity {
private Set<String> texts;
public Set<String> getTexts(){
if(this.texts==null)
this.texts=new LinkedHashSet<String>();
return this.texts;
}
public void setTexts(Set<String> texts){
this.texts=texts;
}
}
当我使用Javascript调用myEntityVar.getTexts()
时,返回的对象是HashSet。似乎jsinterop将HashSet的java实现转换为JavaScript。但是,如何使用JavaScript创建新的HashSet以便使用myEntityVar.setTexts(texts)
?我为“文本”参数尝试了一个数组,但这不起作用。因此,我需要以某种方式在JavaScript中使用HashSet。
但是,我不知道在哪里找到它。
有想法吗?
答案 0 :(得分:6)
简短的回答是,您不能-但是再一次,您也不能在JS中创建普通的HashSet!
之所以完全有效,是因为您已启用-generateJsInteropExports
,并且MyEntity
类型上有一个JsInterop批注,而java.util.Set
上也有一个(并且其他一些基本的JRE类型)。这样可以使您的代码无问题地返回仿真的Java集-支持与JS中运行兼容的任何方法。
有一些缺点:
toArray()
和toArray(T[])
看起来像JS中的相同方法。 GWT通过完全不支持第二种方法来解决此问题。 (java.util.List
与remove(T)
和remove(int)
有相同的问题,但是它在编译时通过将remove(int)
重命名为removeAtIndex(int)
来解决。)如果您从不返回这些类型,则可能要完全禁用此功能-编译器的-excludeJsInteropExports
和-includeJsInteropExports
标志可让您控制要导出的内容。
要更直接地回答您的问题,我可以看到一些选择:
setTexts
方法从JS传递其他内容,例如JsArrayLike
,以便您可以让用户传递纯字符串数组JS甚至是JS Set。您可以走得更远并接受Object
,然后对其进行类型检查以查看传入的内容。您甚至可以保留Set
覆盖,以便在必要时可以从您自己的Java中调用它,但请标记设置为@JsIgnore
,这样当您尝试导出重载方法时GWT不会中断。在某处创建工厂方法以创建您希望JS用户使用的Set实现。由于支持add
和remove
,因此调用JS代码可以在传入之前先构建集合。类似这样的东西:
@JsMethod(namespace = "my.Util")
public static <T> LinkedHashSet<T> createSet() {
return new LinkedHashSet<>();
}
现在他们可以调用my.Util.createSet()
,附加项目,然后将其传递给您的setTexts方法。