java - 如何将对象转换为 JsType?
问题描述
为了操作符合 [GeoJson][1] 的数据,我声明了以下 JsType:
@JsType
public class FeatureCollection extends GeoJson {
@JsProperty
private Feature[] features;
public FeatureCollection() {
super("FeatureCollection");
features = new Feature[]{};
}
public Feature[] getFeatures() {
return features;
}
有时我需要将我的FeatureCollection
对象传递给通过属性访问数据的外部库(例如 Turfs.js 以执行单位转换)features
。该库返回给我一个具有相同属性的新对象(它们像我的 JsType 一样遵循 GeoJson RFC),但我无法将其转换回FeatureCollection
:
FeatureCollection fc = new FeatureCollection();
Object o = TurfUtils.toWgs84(fc); // Works and give an object which respect the FeatureCollection scheme (ie an array of Features) when I print it on the javascript console.
FeatureCollection featureCollection = TurfUtils.toWgs84(fc); // Throw a java.lang.ClassCastException
Turf 库是 JsInteroped:
@JsType(isNative = true, namespace = GLOBAL, name = "turf")
public class TurfUtils {
public static native <T extends GeoJson> T toWgs84(T geojson);
}
当使我的 FeatureCollection 成为本机 JsType 时,它可以工作但阻止我使用我当前的构造函数,所以我正在寻找一种方法将 javascript 对象强制转换为我的 JsType。[1]:https ://www.rfc-editor.org/rfc/rfc7946
解决方案
和相关的@JsType
注解不会创建试图理解你想要做什么的包装器,但它们实际上会生成尽可能接近你所做的事情的 JS 代码。这意味着,如果你说“我正在创建一个新的非本地 JS 类型,并且它将有一个像这样定义的构造函数”,GWT 会说“好的”并去做。结果将是 JS 中具有构造函数的类型,但根据定义未使用该确切构造函数创建的对象不是该类型,如果您尝试将它们视为它们,您可能会收到错误。
相反,您FeatureCollection
几乎可以肯定是本机类型,可能Object
在JsPackage.GLOBAL
名称空间中很简单,并且您应该有一个工厂方法,而不是构造函数。
或者,你可以冒险Js.uncheckedCast
说“相信我,这个对象的形状或多或少是正确的(尽管它可能是错误的类型),只要像它是相同的类型一样使用它”,只要 GWT 没有有理由进一步进行类型检查,它会让你侥幸逃脱。这可能适合在您自己的应用程序代码中使用,但要非常清楚地说明您正在做什么以及何时会出错。
旁注 - 通常如果你在非本地有 getter 和 setter JsType
,你应该将它们标记为@JsProperty
而不是标记私有字段 - 如果你将字段设为 final ,其他 JS 可能会在稍后分配它,如果你做了 getter 或setter 做一些验证或缓存,任何来自 JS 的访问都会错过。还要记住,如果一个类型是 a JsType
,它将自动导出其所有公共成员,因此您可以在这里通过删除JsProperty
和 getter 来实现相同的目的,并使该字段公开。
推荐阅读
- ios - 如何裁剪具有 10 像素偏移的图像?
- javascript - Association.js:39 未捕获的类型错误:无法读取未定义的属性“classList”
- php - php工匠迁移失败
- mysql - 如何在 grafana 查询中使用累积求和变量?
- scala - Scala bazel Worker 进程没有返回 WorkResponse:
- typescript - Javascript 需要 Typescript 导入
- windows - 通过 GUI 时间线 Windows 窗体 C# 控制值
- c++ - 如何将 char 数组声明为函数参数?或者告诉我这段代码还有其他问题?
- virtual-machine - 谷歌云计算:创建 GCP 虚拟机:超出配额“NVIDIA_K80_GPUS”。限制:欧洲西部地区 1.0
- xamarin.forms - Visual Studio 2019 加载资源时速度极慢