You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Graal.js处理自定义Java数值类型?

解决Graal.js中自定义Number子类的算术运算兼容问题

方案一:给自定义JSNumber类添加valueOf()方法

在你的Java类JSNumber中添加valueOf()方法,返回对应的数值类型,Graal.js在进行算术运算时会自动调用该方法获取数值,而非直接转字符串:

public class JSNumber extends Number {
    // 原有业务代码...
    
    // 添加valueOf方法,返回实际数值
    public double valueOf() {
        return this.doubleValue();
    }
    
    // 若以整数运算为主,也可返回int类型
    // public int valueOf() {
    //     return this.intValue();
    // }
}

添加后,JS执行e.id + 1时会先调用e.id.valueOf()拿到数值,再和1做加法运算,结果会是2而非12,完全匹配原有Nashorn的行为。

方案二:实现Graal.js运算符重载方法

如果需要精细控制每个运算符的行为,可以给JSNumber添加对应运算符的重载方法。以加法为例:

public class JSNumber extends Number {
    // 原有业务代码...
    
    public Number $add$(Object other) {
        if (other instanceof Number) {
            double sum = this.doubleValue() + ((Number) other).doubleValue();
            // 根据业务需求返回JSNumber实例或原生数值
            return new JSNumber(sum);
        }
        // 兼容字符串转数值的场景
        if (other instanceof String) {
            try {
                double otherVal = Double.parseDouble((String) other);
                return new JSNumber(this.doubleValue() + otherVal);
            } catch (NumberFormatException e) {
                // 按原有逻辑处理非数值字符串的情况
                return super.toString() + other;
            }
        }
        return super.toString() + other;
    }
}

同理可实现减法($sub$)、乘法($mul$)等其他运算符的重载方法,完全复刻原有业务逻辑。

方案三:通过上下文配置启用自动类型适配

创建Graal.js的Context时,配置选项让Java的Number子类自动转换为JS原生数值:

Context context = Context.newBuilder("js")
    .option("js.java-number-to-primitive", "true")
    .build();

该配置会让Graal.js自动识别JavaNumber子类为数值类型,无需修改JSNumber类即可支持算术运算。注意不同Graal.js版本的配置选项可能略有差异,需对应版本调整。


内容的提问来源于stack exchange,提问作者Erik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 22:45:30