3c20ed6d3407505ad896b11.jsJ
12:18:22.706/E: The method 'boolean java.lang.Object.equals(java.lang.Object)' was expected to be of type interface but instead was found to be of type virtual (declaration of 'org.mozilla.javascript.ScriptRuntime' appears in /data/app/com.hamibot.hamibot-1/base.apk)
java.lang.IncompatibleClassChangeError: The method 'boolean java.lang.Object.equals(java.lang.Object)' was expected to be of type interface but instead was found to be of type virtual (declaration of 'org.mozilla.javascript.ScriptRuntime' appears in /data/app/com.hamibot.hamibot-1/base.apk)
at org.mozilla.javascript.ScriptRuntime.jsDelegatesTo(Unknown Source)
at org.mozilla.javascript.BaseFunction.hasInstance(Unknown Source)
at
回答
这个错误是由于 JavaScript 引擎 Rhino 在处理某些语法或对象比较时发生了不兼容的类变更(IncompatibleClassChangeError),通常出现在使用了不被 Rhino 1.7.15 支持的现代 JavaScript 特性,或者在进行对象类型判断、继承操作时出现了底层引擎冲突。
错误原因分析:
你遇到的错误:
The method 'boolean java.lang.Object.equals(java.lang.Object)' was expected to be of type interface but instead was found to be of type virtual
表明 Rhino 的运行时尝试将某个方法当作接口方法调用,但实际发现它是虚拟方法。这通常是以下几种情况导致的:
- 使用了不兼容的语法:比如箭头函数、扩展运算符、class 继承等 ES6+ 特性。
- 对内置对象进行了非法的 instanceof 或 hasInstance 操作。
- 脚本中存在与 Java 层交互时类型混淆的情况,例如把 Java 对象和 JS 对象混用做判断。
- 自定义了
toString,valueOf或原型链修改不当,导致 Rhino 在类型转换时出错。
解决方案
✅ 1. 避免使用现代 JavaScript 语法
Hamibot 使用的是 Rhino 1.7.15,不支持 ES6+ 的大部分特性。请确保你的代码符合旧版 JavaScript 标准。
错误写法示例(禁止):
// ❌ 箭头函数
list.forEach(item => log(item));
// ❌ class 定义
class Person {}
// ❌ 扩展运算符
const arr = [...otherArr];
// ❌ 默认参数
function greet(name = 'Guest') {}
正确写法:
// ✅ 普通函数
list.forEach(function(item) {
log(item);
});
// ✅ 使用构造函数代替 class
function Person(name) {
this.name = name;
}
✅ 2. 不要对 null 或 undefined 使用 instanceof
避免对可能为 null 或 undefined 的值执行 instanceof 判断。
错误写法:
if (obj instanceof Array) { ... } // 如果 obj 是 null,可能导致异常
安全写法:
if (Array.isArray(obj)) {
// 推荐方式
}
// 或
if (obj && obj instanceof Array) {
...
}
✅ 3. 避免修改原生对象原型
不要随意修改 Object.prototype、String.prototype 等。
禁止:
Object.prototype.custom = function() {}; // 可能引发引擎内部逻辑错乱
✅ 4. 检查是否误用了 Java 对象的方法
当你通过 Hamibot API 获取到一个对象(如控件、图像、设备对象),不要将其当作普通 JS 对象进行复杂判断或继承操作。
例如:
var w = floaty.window(...);
if (w instanceof Function) { ... } // ❌ 不要这样判断
建议的最佳实践
- 使用标准的函数声明和变量定义。
- 多用
typeof和Array.isArray()而非instanceof。 - 不要使用 Babel/TypeScript 编译后的代码直接运行,除非明确降级到 ES5。
- 出现此类错误时,注释掉最近添加的代码段逐步排查。
示例修复代码
// 文档地址 https://docs.hamibot.com/
// 正确的通用日志遍历
var items = ["a", "b", "c"];
for (var i = 0; i < items.length; i++) {
log(items[i]);
}
// 或使用匿名函数形式的 forEach
items.forEach(function(item) {
log(item);
});
// 判断数组的安全方式
if (Array.isArray(items)) {
log("这是一个数组");
}
如果你能提供出错的具体代码片段,我可以进一步定位哪一行触发了该问题并给出精确修改建议。