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

时间:2014-02-14 14:29:28

标签: java oop generics interface rhino

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

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 mocks 通用接口的大量结果,而不是Rhino JS通用接口实现。

1 个答案:

答案 0 :(得分:3)

从少数几个Javascript来看,没有泛型,没有接口,甚至没有类。在Javascript中,您有Objects with functions that may be created from prototypes

在Javascript中“实现”Java接口只意味着提供一些Javascript对象,它具有与interfaces方法名称相同的函数名称,并且这些函数与相应的接口方法具有相同数量的参数。

因此,要实现您提供的通用示例接口,您可以编写如下内容:

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就是这个功能   可以通过JavaScript和Java接口扩展哪个Java类   由JavaScript实现。我们已经取代了Rhino的JavaAdapter   使用我们自己的JavaAdapter实现。在我们的实施中,   JavaScript对象只能实现单个Java接口。

因此,如果您需要这些功能,则无论如何都需要安装原始的Rhino实现(这样可以更轻松地设置源代码)。