tutorial español engine java javascript rhino

español - Rhino: los números de Java no se comportan como los números de Javascript



rhino javascript engine download (2)

Esta es una característica extraña de Rhino: un Number Java configurado con engine.put("one", new Double(1)) funciona como se esperaba, mientras que el resultado de un método Java depende del tipo de retorno declarado por el propio método, que Se lee con la API de reflexión:

  • Si es una primitiva, como el double , se convierte a un número de Javascript.
  • de lo contrario, se maneja como otros objetos host y el + significa concatenación, ya sea Object como en su muestra, así como Double

Puede configurar este comportamiento con wrapFactory.setJavaPrimitiveWrap(false) en WrapFactory en el Context actual. De esta manera, el código de Rhino se puede mantener en las líneas de arranque de su programa y no saturará a ContentProvider (que creo que es una especie de proxy de configuración)

Desde el Javadoc en vivo de WrapFactory.isJavaPrimitiveWrap()

De forma predeterminada, el método devuelve verdadero para indicar que las instancias de Cadena, Número, Booleano y Carácter deben incluirse como cualquier otro objeto Java y los scripts pueden acceder a cualquier método Java disponible en estos objetos.

Por lo tanto, puede establecer este indicador en false para indicar que los Number Java deben convertirse a números de Javascript. Solo lleva dos líneas de código.

Context ctx = Context.enter(); ctx.getWrapFactory().setJavaPrimitiveWrap(false);

Aquí está la esencia con el código completo que solía probar.

Tengo una instancia de esta clase de Java accesible en mi programa de Javascript

public class ContentProvider { public Object c(int n) { switch (n) { case 1: return 1.1; case 2: return 2.2; case 3: return 3.3; case 4: return "4"; case 5: return new java.util.Date(); } return null; } }

Este es el código dentro de main ():

ScriptEngineManager mgr = new ScriptEngineManager(); ScriptEngine engine = mgr.getEngineByName("JavaScript"); engine.put("ctx", new ContentProvider()); res = engine.eval("ctx.c(1)"); System.out.printf("rhino:> %s (%s)%n" , res , res != null ? res.getClass().getName() : null );

La expresión simple ctx.c(1) imprime:

rhino:> 1.1 (java.lang.Double)

Ahora, esto es lo que sucede con ctx.c(1) + ctx.c(2) :

rhino:> 1.12.2 (java.lang.String)

Y finalmente (ctx.c(1) + ctx.c(2)) * ctx.c(3) :

rhino:> nan (java.lang.Double)

¡Rhino está realizando concatenación de cuerdas en lugar de aritmética numérica! El siguiente programa funciona como se espera en su lugar:

engine.put("a", 1.1); engine.put("b", 2.2); engine.put("c", 3.3); res = engine.eval("(a + b) * c");

Salidas:

rhino:> 10,89 (java.lang.Double)


He creado una envoltura de valor:

public static class JSValue extends sun.org.mozilla.javascript.internal.ScriptableObject { Object value; public JSValue(Object value) { this.value = value; } public String getClassName() { return value != null? value.getClass().getName(): null; } @Override public Object getDefaultValue(Class typeHint) { if (typeHint == null || Number.class.isAssignableFrom(typeHint)) { if (value instanceof Number) return ((Number) value).doubleValue(); } return toString(); } @Override public String toString() { return value != null? value.toString(): null; } }

y una función de edición:

public static class ContentProvider { public Object c(int n) { ... return new JSValue(1.1);

Ahora la expresión funciona como se espera. Gracias a todos.