gpt4 book ai didi

gwt - Js.cast() 如何执行类型检查?

转载 作者:行者123 更新时间:2023-12-02 02:50:42 26 4
gpt4 key购买 nike

我正在使用 GWT 2.9 和 elemental2-1.0.0-RC1。

以下代码在运行时抛出 ClassCastException:

DocumentRange documentRange = Js.cast(DomGlobal.document); // Fails
Range range = documentRange.createRange(); // Never reaches here

当我改为使用 Js.uncheckedCast() 时,它会成功:

DocumentRange documentRange = Js.uncheckedCast(DomGlobal.document);
Range range = documentRange.createRange(); // Works

Js.uncheckedCast() 的文档说:

"You should always prefer regular casting over this (unless you know what you are doing!)."

我不知道为什么我必须使用它,所以我感到紧张。有人可以解释一下 Js.cast() 如何执行类型检查以及为什么我需要在这种情况下使用 Js.uncheckedCast() 吗?

最佳答案

Js.cast() 是一种作弊的方式,它会做一些 Java 语言不允许但实际上可能合法的事情。忽略“它实际上是如何工作的”,我们的想法是,您现在可以解决 Java 会提示的问题,即使结果证明它是合法的。

一个例子是,您采用 java.lang.Doubledouble 并希望将其视为 JsNumber,这样您就可以调用 toPrecision(2) 。由于 java.lang.Double 是最终的,因此转换为不相关的类型是不合法的,但 Java 不知道在 GWT 中,Double 实际上只是一个 js Number.因此,您可以使用 Js.cast() 执行转换。编译器将在其中插入运行时类型检查,在运行时验证您的号码实际上是 JS Number 实例。

另一个示例可能是尝试扩展 elemental2 提供的某些 native 类型,以实现缺少功能的解决方法,或者执行特定于浏览器的操作。你的新类可能不会扩展现有的类 - 从 JS 的角度来看,这没关系,你只是在描述你知道在运行时存在的 API。因此,我们需要避免 Java 语言检查“这个强制转换是否有意义?”,而只是告诉编译器尝试一下。

另一方面,您可以使用 Js.uncheckedCast() 对编译器“撒谎”。这用于您甚至要求运行时跳过检查并假装它会起作用的情况。这可以让你做一些奇怪的事情,比如将字符串视为数组,或者解决跨框架问题。不会发出运行时检查,因此如果缺少方法/属性,您可能只会得到 TypeError,而不是正确的 ClassCastException。


在elemental2-dom 1.0.0-RC1中,有一个名为DocumentRange的类,但它实际上没有任何意义 - 它被声明为一个类,这意味着它可以进行类型检查JS,但浏览器规范说它应该是一个“接口(interface)”(在 JS 领域意味着它只是类型的描述,而不是可以进行类型检查的东西)。 https://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level2-DocumentRange-method-createRange

这个bug继承自closure-compiler,它声称它有一个构造函数:https://github.com/google/closure-compiler/blob/6a418aa/externs/browser/w3c_range.js#L241-L251

修复是让闭包编译器将其引用为接口(interface),并发布新版本的 elemental2,以便您可以使用它。


您可以在此处采取两种解决方法。第一种是使用 Js.uncheckedCast(DomGlobal.document) 作弊并说“是的,我知道 Document 不是 instanceof DocumentRange,但那是因为没有像 DocumentRange 这样的类,所以就假装它有效,这样我就可以对其调用 createRange() ”。这就是您已经在做的事情 - 它隐藏了存在错误的事实,但最终它是有效的。

“正确”的答案是声明您自己的 DocumentRange,并对其执行 Js.cast() 。这仍然很恶心 - 你必须保留你的新界面,直到修复修复,然后 elemental2 被释放,然后你必须记住清理它。

在这种情况下,我建议对 GWT 撒谎并使用 Js.uncheckedCast() - 这里只有一个方法,并且不太可能以有意义的方式进行更改。

关于gwt - Js.cast() 如何执行类型检查?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62018107/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com