java-如何在Rhino JS中实现通用接口?

我有一个包含通用接口的应用程序:

public interface IMyInterface<T> {
    public int calcStuff(T input); 
}

我可以用Java清楚地实现这一点:

public class Implementor implements IMyInterface<FooObject>{
    public int calcStuff(FooObject input){ ... }
}

我已经找到了有关在Rhino中实现Java非通用接口的教程,并且可以验证它是否可以在我的上下文中使用.

据我了解,由于动态类型系统和其他因素,Javascript没有泛型,因此Rhino在其JS解析器中没有提供这样的让步.任何进行研究的尝试都会使我获得有关Rhino模拟通用接口而不是Rhino JS通用接口实现的大量结果.

解决方法:

从Java语言的角度来看,没有泛型,没有接口甚至没有类.在Javascript中,您有Objects with functions that may be created from prototypes.

在Javascript中“实现” Java接口仅意味着提供一些Javascript对象,该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类:

> https://github.com/mozilla/rhino/blob/master/src/org/mozilla/javascript/jdk13/VMBridge_jdk13.java
> https://github.com/mozilla/rhino/blob/master/src/org/mozilla/javascript/InterfaceAdapter.java

本质上,静态方法InterfaceAdapter#create()将调用VMBridge#newInterfaceProxy(),该方法返回接口的Java代理,该代理使用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’s JavaAdapter has been overridden. JavaAdapter is the feature by
which Java class can be extended by JavaScript and Java interfaces may
be implemented by JavaScript. We have replaced Rhino’s JavaAdapter
with our own implementation of JavaAdapter. In our implementation,
only single Java interface may be implemented by a JavaScript object.

因此,如果您需要这些功能,则无论如何都需要安装原始的Rhino实现(这使得设置源代码更加容易).

上一篇:使用Javascript Rhino重载Java方法


下一篇:小猪cms微信二次开发之怎样分页