سؤال

I have an application that contains a generic interface:

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

I can clearly implement this in Java:

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

I have found a tutorial on implementing Java non-generic interfaces in Rhino and can verify that it works in my context.

As far as I understand Javascript has no generics due to the dynamic type system and other factors, so Rhino does not provide such a concession in its JS parser. Any attempts to do research lead me to a plethora of results about Rhino mocks generic interfaces but not Rhino JS generic interface implementation.

هل كانت مفيدة؟

المحلول

From a Javascript point of few, there are no generics, no interfaces, not even classes. In Javascript you have Objects with functions that may be created from prototypes.

To "implement" a Java interface in Javascript only means, to provide some Javascript object, that has the same function names as the interfaces method names, and these functions have the same number of arguments as the corresponding interface methods.

So to implement the generic example interface you provided, you can write something like this:

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();
    }

Here it is assumed, that the intended generic class is of type String.

Now lets say, you have a Java class, that accepts this interface with a generic String type:

public static class MyClass {
    public static void callMyInterface(IMyInterface<String> myInterface){
        System.out.println(myInterface.calcStuff("some Input"));
    }
}

You can then call this method from Javascript like so:

// do some Java thing with the generic String type interface
Packages.myPackage.MyClass.callMyInterface(new Packages.myPackage.IMyInterface(myInterfaceImpl)));

Some background information on the topic

If you are interested in what goes on behind the scenes in Rhino, when implementing a Java interface in Javascript, I recommend to have a look at the following Rhino classes:

Essentially the static method InterfaceAdapter#create() will call VMBridge#newInterfaceProxy(), which returns a Java Proxy for the interface, that uses an instance of InterfaceAdapter to handle method invocations on your interface. This proxy will map any Java method call on the interface to the corresponding Javascript functions.

 **
 * 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)

When I first worked with generic interfaces in both Java and Javascript, it also helped me quite a lot to understand what is going on, by step debugging my invocations on the created Rhino proxies (but you will of course need the Rhino source to do that, and setting it up can be a little cumbersome).

Also note, that the default Rhino implementation used by the Java Scripting API does not allow to implement multiple Java interfaces or to extend Java classes. From the 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.

So if you need these features, you will need to install the original Rhino implementation anyway (which makes it easier to set up the source code).

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top