2011-11-21 11 views
10

Tome la siguiente prueba:¿Puedo desambiguar a la fuerza métodos sobrecargados llamados por Rhino?

public static class Scripted { 
    public void setThing(List<?> list) { 
     System.out.println("Set via list"); 
    } 

    public void setThing(Object[] array) { 
     System.out.println("Set array"); 
    } 
} 

@Test 
public void testScripting() throws Exception { 
    ScriptEngine engine = new ScriptEngineManager().getEngineByExtension("js"); 
    engine.getContext().setAttribute("s", new Scripted(), ScriptContext.ENGINE_SCOPE); 
    engine.eval("s.thing = Array(1, 2, 3);"); 
} 

Con la versión de envío Rhino con Java 7, si ejecuta esto, obtendrá una excepción de esta manera:

javax.script.ScriptException: sun.org.mozilla.javascript.internal.EvaluatorException: The choice of Java constructor setThing matching JavaScript argument types (object) is ambiguous; candidate constructors are: 
    void setThing(java.util.List) 
    void setThing(java.lang.Object[]) (<Unknown source>#1) in <Unknown source> at line number 1 

La existencia Object[] sobrecarga en el El primer lugar se debe a que la versión anterior de Rhino no convertía automáticamente las matrices a List, pero las convertiría a en Object[].

Si se tratara de un proyecto personal, aquí es donde simplemente eliminaría la sobrecarga Object[]. El problema es que esta es una API pública y podría haber alguien llamando a ese método en este momento. Todavía me gustaría actualizar a Java 7 pero me gustaría evitar molestar tanto a los usuarios de JavaScript como a las personas que usan la versión de matriz del método.

¿Hay alguna manera de ocultar los métodos sobrecargados Object[] de Rhino, mientras que otros todavía podrían llamarlos?

Respuesta

10

Aunque no es muy elegante, hay una manera de llamar específicamente a un método Java sobrecargado. Se define en la última sección de la especificación Java Method Overloading and LiveConnect 3. Básicamente, utiliza la firma completa del método al que desea llamar, tal como se muestra en el mensaje de error, usando la notación de corchetes. En su caso, el siguiente debería funcionar:

s["setThing(java.util.List)"](Array(1, 2, 3)); 

Es un poco lamentable que el cambio que hicimos con matrices de JavaScript implementar java.util.List rompe el código existente. Tal vez sería mejor simplemente elegir uno en caso de que haya múltiples métodos de coincidencia.

+0

Estoy de acuerdo ... Hubiera sido mejor si se acaba de llamar la Lista uno sin dejar de esta manera. Pero Java 7 ha roto bastantes otras cosas en nuestra aplicación, esta es solo una de las muchas (las otras, como los cambios de la configuración regional, están resueltas). – Trejkaz

Cuestiones relacionadas