从少数 Javascript 的角度来看,没有泛型,没有接口,甚至没有类。在 Javascript 中,您有 Objects with functions that may be created from prototypes。
在 Javascript 中“实现”一个 Java 接口仅意味着提供一些 Javascript 对象,该对象具有与接口方法名称相同的函数名称,并且这些函数具有与相应接口方法相同数量的参数。
所以要实现你提供的通用示例接口,你可以这样写:
myGenericInterfaceImpl = new Object();
// Generic type is supposed to be <String> int calcStuff(String)
myGenericInterfaceImpl.calcStuff = function(input) {
println("--- calcStuff called ---");
println("input" + input);
println("typeof(input):" + typeof(input));
// do something with the String input
println(input.charAt(0));
return input.length();
}
这里假设预期的泛型类是String 类型。
现在假设你有一个 Java 类,它接受这个具有通用 String 类型的接口:
public static class MyClass {
public static void callMyInterface(IMyInterface<String> myInterface){
System.out.println(myInterface.calcStuff("some Input"));
}
}
然后你可以像这样从 Javascript 调用这个方法:
// do some Java thing with the generic String type interface
Packages.myPackage.MyClass.callMyInterface(new Packages.myPackage.IMyInterface(myInterfaceImpl)));
关于该主题的一些背景信息
如果您对 Rhino 的幕后工作感兴趣,在 Javascript 中实现 Java 接口时,我建议您查看以下 Rhino 类:
本质上,静态方法InterfaceAdapter#create() 将调用VMBridge#newInterfaceProxy(),它为接口返回一个Java Proxy,它使用InterfaceAdapter 的实例来处理接口上的方法调用。此代理会将接口上的任何 Java 方法调用映射到相应的 Javascript 函数。
**
* Make glue object implementing interface cl that will
* call the supplied JS function when called.
* Only interfaces were all methods have the same signature is supported.
*
* @return The glue object or null if <tt>cl</tt> is not interface or
* has methods with different signatures.
*/
static Object create(Context cx, Class<?> cl, ScriptableObject object)
当我第一次在 Java 和 Javascript 中使用通用接口时,通过逐步调试我在创建的 Rhino 代理上的调用(但你当然需要 Rhino 源要做到这一点,并且设置它可能有点麻烦)。
另外请注意,Java Scripting API 使用的默认 Rhino 实现不允许实现多个 Java 接口或扩展 Java 类。来自Java Scripting Programmer's Guide:
Rhino 的 JavaAdapter 已被覆盖。 JavaAdapter 是由
哪些 Java 类可以被 JavaScript 和 Java 接口扩展
由 JavaScript 实现。我们已经替换了 Rhino 的 JavaAdapter
使用我们自己的 JavaAdapter 实现。在我们的实施中,
JavaScript 对象只能实现单个 Java 接口。
因此,如果您需要这些功能,则无论如何都需要安装原始的 Rhino 实现(这样更容易设置源代码)。