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

GWT JSNI调用Java方法报错:JavaScriptException TypeError:方法不是函数

GWT调用Java实例方法报错:that_0_g$.doThing_0_g$ is not a function

问题概况

尝试通过JavaScript的onclick事件调用GWT中StartView类的doThing()实例方法,编译通过但触发点击时控制台抛出错误:

Exception: com.google.gwt.core.client.JavaScriptException: (TypeError) : that_0_g$.doThing_0_g$ is not a function

控制台输入window.doThing可正常返回函数,但调用时触发上述异常。相关代码如下:

关联代码

StartView.java(初始化时调用StartView.loadJS()):

public void doThing() {
    System.out.println("do thing");
}

public static native void loadJS() /*-{
    var that = this;
    $wnd.doThing = $entry(function() {
        that.@package.StartView::doThing()();
    });
}-*/;

外部start.js(通过ScriptInjector注入):

// onclick 处理逻辑内
window.doThing();

错误根源

loadJS()是static静态方法,此时this指向的是StartView类本身(而非类的实例对象),但doThing()是实例方法——类本身并不拥有该方法,只有类的实例才具备,因此编译后尝试调用类上的doThing_0_g$方法必然失败。

解决方法

方案1:修正JSNI的this指向(适配现有代码)

将loadJS()改为实例方法,确保this指向StartView的实例:

// 改为实例方法,移除static修饰符
public native void loadJS() /*-{
    var that = this;
    $wnd.doThing = $entry(function() {
        that.@package.StartView::doThing()();
    });
}-*/;

// 初始化时用实例调用该方法
StartView viewInstance = new StartView();
viewInstance.loadJS();

方案2:使用JSInterop替代JSNI(更简洁可靠)

利用GWT的JSInterop注解直接将实例方法绑定到全局window,避免this指向混淆:

import jsinterop.annotations.JsMethod;
import jsinterop.annotations.JsPackage;
import jsinterop.annotations.JsType;

@JsType(isNative = false, namespace = JsPackage.GLOBAL)
public class StartView {
    public void doThing() {
        System.out.println("do thing");
    }

    @JsMethod(name = "doThing")
    public static void bindToWindow(StartView instance) {
        // 将实例方法绑定到全局window对象
        $wnd.doThing = () -> instance.doThing();
    }
}

// 初始化时传入实例完成绑定
StartView view = new StartView();
StartView.bindToWindow(view);

额外注意点

  • 确保StartView实例在window.doThing()调用期间未被GWT垃圾回收,可将实例存储在全局变量或保留类级别的引用。
  • 验证编译模式:开发模式与生产模式的JS绑定逻辑存在差异,建议在生产编译环境下测试效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 01:11:39