更新:根据各种反馈,我大幅更新了我的问题,使其与原始问题不同(尽管仍然相关)。我不知道 StackOverflow 上的正确协议是什么,所以如果我做错了事情,我很抱歉。
我正在使用 Java 实现的流行软件即服务平台工作,该平台使用 Rhino JavaScript 引擎执行客户 JavaScript 代码。他们的 API 之一是 GlideRecord(你可以通过 Google 搜索找到该平台,但我没有提及它,因为我认为它与我的问题没有密切关系),这是客户用来针对MySQL数据库,所有数据都存储在平台上。
当我通过 GlideRecord API 访问特定字段值时,该字段值以名为 GlideElement 的对象的形式提供:
// JavaScript code
let gr = new GlideRecord(tableName);
gr.get(recordID);
let ge = gr[fieldName]; // GlideElement object
借助 Rhino 引擎的魔力,GlideRecord 和 GlideElement 都不是 JavaScript 对象,而是以某种方式共享到 JavaScript 运行时的 Java 对象。 GlideElement 对象的奇怪之处在于它似乎是 java.lang.String 的一个实例:
ge instanceof GlideElement; // true
ge instanceof Packages.java.lang.String; // true
(
Packages
对象是由Rhino提供的,作为访问java.lang.String
之类的东西的一种方式。这看起来很可疑,但据我所知,它是来自Java的真正的java.lang.String
,没什么好笑的。)
我最初的问题是问某个东西如何成为两个类的实例,我现在明白这是通过多态性(子类化和接口实现)实现的普通事情。但是,java.lang.String 类是一个
final
类,因此它不应该由任何其他类进行子类化或实现。
不幸的是,上面的代码是我能提供的全部内容,因为 SaaS 平台的 Java 代码不是开源的,所以我无法(也没有人能)看到 GlideRecord 和 GlideElement 是如何在幕后实现的。如果无法访问源代码,我们能知道或推测如何在普通 Java 或由 Rhino 引擎启用的一些神秘女巫魔法中实现这一点吗?
有没有一种纯Java方法可以让对象通过这两个instanceof测试?
是的,而且这种事经常发生。不需要魔法或奇怪的结构。只是
extends
或 implements
。
这里是否还有一些特定于 Rhino JavaScript 引擎的其他魔法?
可能是;但是你不需要“rhino javascript引擎魔法”来解释单个对象
instanceof
不止一种类型的概念,因为根据定义,每个java对象除了字面上的new Object()
:
instanceof
不检查“表达式是否是这个确切类的实例”。尽管有名字。
它检查“表达式是否是该确切类型的实例或作为其子类型的任何类”。
“简单”(且不正确)的视图(仅检查它是否是指定的类)听起来不错,但几乎完全没用。这意味着例如执行
instanceof Number
或 instanceof List
是没有用的,因为它必然会返回 false
(Number 和 List 是接口/抽象类;不可能创建一个专门作为它们实例的对象;new Number()
是不合法的,也不是new List()
)。许多设计将所有实际的具体类型作为非公开的。您可以通过工厂构造函数来制作它们,唯一可用的公共类型是某种超类型。 instanceof
在那里毫无用处。
如果
x instanceof Type
返回 true
,那么您可以将 x
转换为 Type 并且它会起作用。这是一个有用的操作,也是 instanceof
的作用。
记住 -
class Y extends X
意味着 Y 被设计为:采用 class X{}
定义的 一切。每个领域,每个方法。 Y 拥有这些东西的所有。现在 Y 可以定义 Y 拥有的更多东西,但是,它不能夺走东西。
换句话说,给定
class Y extends X
,练习的重点是您可以将 Y 的实例视为 X。因为它们是。
正确的术语是 is a。
class Integer extends Number
表示“整数 的任何实例都是 数字”。有了这个术语,很明显为什么 Integer i = 5; System.out.println(i instanceof Number);
会打印 true
。因为 i
是 Number
。
你有宠物狗吗?假设你愿意。
Rover 是一只狗。
Rover 是一种动物。
rover instanceof Animal
是true
。这应该是显而易见的、合乎逻辑的。 rover instanceof Dog
也是true
。希望这具有内在意义。
没问题。您正在寻找
.getClass()
而不是 instanceof
:
Number n = Integer.valueOf(5);
System.out.println(n instanceof Integer); // true
System.out.println(n instanceof Number); // true
System.out.println(n instanceof Object); // true
System.out.println(n instanceof Double); // false
System.out.println(n.getClass() == Integer.class); // true
System.out.println(n.getClass() == Number.class); // false