java 板


LINE

Blog 版:http://blog.dontcareabout.us/2014/04/js-java-static-method.html BBS 版以 markdown 语法撰写 ______________________________________________________________________ 内容有点无脑,先把结论写在前面: > 外部 JS(官方文件称为「handwritten JS」, > 其实不同 GWT Module 就满足这个条件)要呼叫 Java 的 static method, > 必须先透过 JSNI 设定 `$wnd.methodName = > @fooPackage.FooClass::javaMethodName(*)`, > 後续使用 `$wnd.methodName()` 来达到目的。 > > 关键在於 JSNI 中: > > * `javaMethodName()` 後头不需再加 `()`。 > * `javaMethodName()` 的参数某些情况下可以省略 field descriptor, > 直接用 `*` 代替。 update:感谢 darkk6(ptt.cc)提醒,让我发现我不但死脑筋, 而且还少测了一种写法... 所以文章就要重新翻修了 (艹 前天被问到一个问题: 「同一个 host page 上两个不同 GWT Module 要怎麽沟通?」 我原本以为这不会是问题, 结果回到家实际测了一下才发现根本不是这麽一回事 [死]。 一言以蔽之,可以用这个 [stackoverflow][so1] 来解释。 上头发问的内容大抵上就是我原本的想法:用 event bus 来解, 结果是不可行的,不过那不是这篇文章的重点 XD [so1]: http://stackoverflow.com/questions/17273572/ how-to-communicate-two-modules-in-gwt?answertab=votes#tab-top 为了保险起见实际测试了一下解答的 code,然後就发现根本行不通: private native static exportMyJavaMethod() /*-{ $wnd.myJavaMethod = @my.package.module1.MyClass1::myJavaMethod; }-*/; 那个 `myJavaMethod` 没给参数的 field descriptor, GPE 就报 syntax error、development mode 也一样炸。 回头去确认[官方文件],没想到[官方文件]的程式码一样微妙...... package mypackage; public MyUtilityClass{ public static int computeLoanInterest( int amt, float interestRate, int term) { ... } public static native void exportStaticMethod() /*-{ $wnd.computeLoanInterest = $entry( @mypackage.MyUtilityClass::computeLoanInterest(IFI) ); }-*/; } 我不太确定那个 `IFI` 是啥意思 or 啥缩写...... ==" [官方文件]: http://www.gwtproject.org/doc/latest/ DevGuideCodingBasicsJSNI.html#calling 好,不管这些,自己重新写一个程式测试这个部份: package foo.client; //import 略 public class FooEP implements EntryPoint { @Override public void onModuleLoad() { exportJsMethod(); callFooMethod("..."); } static void javaMethod(String arg1) { Window.alert("javaMethod : " + arg1); } native static void exportJsMethod() /*-{ $wnd.fooMethod = @foo.client.FooEP::javaMethod (Ljava/lang/String;)(); }-*/; native static void callFooMethod(String message) /*-{ $wnd.fooMethod(message); }-*/; } 结果在 development mode 执行就炸错误,主要错误讯息是 com.google.gwt.core.client.JavaScriptException: (TypeError) @foo.client.FooEP::callFooMethod()([]): undefined is not a function 其实在这错误讯息之前就有两个地方散发出怪味道: 1. `$wnd.fooMethod = @foo.client.FooEP::javaMethod (Ljava/lang/String;)();`, 为什麽没有实际给 `javaMethod()` 参数? 等等,这个时间点给他什麽都不对啊? 2. 忽略 1,为什麽会先跳出 alert 视窗显示 `javaMethod : null`, 然後才炸错误? 如果也在 `callFooMethod()` 里头先卡一行 `$wnd.alert("WTF?")`, 会发现显示 `WTF?` 的 alert 视窗还是会出现, 表示 `callFooMethod()` 有正确被执行到,炸的是 `$wnd.fooMethod()`。 整个看起来,事情好像就有头绪了。 其实 `exportJsMethod()` 的 `$wnd.fooMethod` 根本没有正确 assign 成 `FooEP.javaMethod()`, 而是 assign 成 `FooEP.javaMethod()` 的回传值──根本没这玩意, 所以到 `callFooMethod()` 的时候当然就炸了。 原先我一直死脑筋用 Java 的角度去看, 後来换成 JS 的角度去看其实这样结果很正常。 在 JS 当中一个变数可以代表一个数值、 也可以代表一个 function / method, 如果程式中要执行该 function / method,那就是加上 `()`, 例如在 Chrome console 输入 `alert` 会得到 `function alert() { [native code] }`, 而 `alert("WTF")` 才会真正跳出 alert 视窗。 在上头的 case 当中,我只是要把 $wnd.fooMethod 指定为一段程式码, 根本没有要执行它的意思,所以加上 `()` 根本就是多余且错误阿... ![](http://img.anyanother.com/data/55495.jpg) 所以拿掉後头的空括号,一切就正常了(之前怎麽没想过阿阿阿阿 [核爆]), [官方文件]的那个 `IFI`, darkk6 猜测是 `int`、`float`、`int` 的缩写, 如今(修正完之後)回头看也很合理了 [死]。 最後不小心看到另一个 [stackoverflow][so2], 发现还有一招里技可以用, 就是直接给 `*` 号,省去打一堆 field descriptor: native static void exportJsMethod() /*-{ $wnd.fooMethod = @foo.client.FooEP::javaMethod(*); }-*/; 这有个前提,就是 `FooEP` 中只能有一个 `javaMethod()`, 否则就会炸错误:也就是说, 如果你有两个以上同名的 method,那还是得乖乖写 field descriptor。 另外,在 JSNI 中呼叫 `$wnd.fooMethod()` 时已经是纯粹 JS 了, 所以即使你多传参数、或是少传参数也不会怎麽样...... 至少 GPE 跟 browser 都没有特别反应。 native static void callFooMethod(String message) /*-{ $wnd.fooMethod(); $wnd.fooMethod(message, "又多余了"); }-*/; [so2]: http://stackoverflow.com/questions/16080099/calling-gwt-java-function-from-javascript?rq=1 好了,事实证明 GWT 文件也没写得那麽好, 除了上次那个很隐晦不想让人知道的 [AutoBean] 之外, 又遇到了一个谜样里技。还是说其实官方文件有,只是我没找到呢...... [泪目] [AutoBean]: http://blog.dontcareabout.us/2013/12/gwt-autobean.html ==== 再次感谢 darkk6 Orz -- 钱锺书: 说出来的话 http://www.psmonkey.org 比不上不说出来的话 Java 版 cookcomic 版 只影射着说不出来的话 and more...... --



※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 114.37.105.127
※ 文章网址: http://webptt.com/cn.aspx?n=bbs/java/M.1398318539.A.066.html
1F:→ darkk6:不客气XDD 是觉得应该和 JNI 的 Signatures 一样才这样猜 04/24 14:07







like.gif 您可能会有兴趣的文章
icon.png[问题/行为] 猫晚上进房间会不会有憋尿问题
icon.pngRe: [闲聊] 选了错误的女孩成为魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一张
icon.png[心得] EMS高领长版毛衣.墨小楼MC1002
icon.png[分享] 丹龙隔热纸GE55+33+22
icon.png[问题] 清洗洗衣机
icon.png[寻物] 窗台下的空间
icon.png[闲聊] 双极の女神1 木魔爵
icon.png[售车] 新竹 1997 march 1297cc 白色 四门
icon.png[讨论] 能从照片感受到摄影者心情吗
icon.png[狂贺] 贺贺贺贺 贺!岛村卯月!总选举NO.1
icon.png[难过] 羡慕白皮肤的女生
icon.png阅读文章
icon.png[黑特]
icon.png[问题] SBK S1安装於安全帽位置
icon.png[分享] 旧woo100绝版开箱!!
icon.pngRe: [无言] 关於小包卫生纸
icon.png[开箱] E5-2683V3 RX480Strix 快睿C1 简单测试
icon.png[心得] 苍の海贼龙 地狱 执行者16PT
icon.png[售车] 1999年Virage iO 1.8EXi
icon.png[心得] 挑战33 LV10 狮子座pt solo
icon.png[闲聊] 手把手教你不被桶之新手主购教学
icon.png[分享] Civic Type R 量产版官方照无预警流出
icon.png[售车] Golf 4 2.0 银色 自排
icon.png[出售] Graco提篮汽座(有底座)2000元诚可议
icon.png[问题] 请问补牙材质掉了还能再补吗?(台中半年内
icon.png[问题] 44th 单曲 生写竟然都给重复的啊啊!
icon.png[心得] 华南红卡/icash 核卡
icon.png[问题] 拔牙矫正这样正常吗
icon.png[赠送] 老莫高业 初业 102年版
icon.png[情报] 三大行动支付 本季掀战火
icon.png[宝宝] 博客来Amos水蜡笔5/1特价五折
icon.pngRe: [心得] 新鲜人一些面试分享
icon.png[心得] 苍の海贼龙 地狱 麒麟25PT
icon.pngRe: [闲聊] (君の名は。雷慎入) 君名二创漫画翻译
icon.pngRe: [闲聊] OGN中场影片:失踪人口局 (英文字幕)
icon.png[问题] 台湾大哥大4G讯号差
icon.png[出售] [全国]全新千寻侘草LED灯, 水草

请输入看板名称,例如:iOS站内搜寻

TOP