JavaScript and Java

, # JavaScript and Java

每个程序员都懂都会写的语言是什么? 我觉得JavaScript当之无愧, 其次呢, 应该是 Java 和 C

在游戏编程中常用Lua作为脚本嵌入语言来描述复杂的逻辑和流程, 现在 JavaScript 来作为嵌入式脚本也是不错的选择

针对如下问题, 简单查阅研究了一番, 总结如下

  1. Java 如何执行 JavaScript? 如何调用 JavaScript 的函数和类方法?

  2. JavaScript 如何调用 Java class methods

  3. 如何把 JavaScript 翻译成另一种脚本语言?

Java JavaScript package

Oracle’s implementation of JDK 7 is co-bundled with the Mozilla Rhino based JavaScript engine which can be used in conjunction with javax.script (JSR-223) API

rhino

The main areas of functionality of javax.script package include

  1. 脚本执行 Script execution: Scripts are streams of characters used as sources for programs executed by script engines. Script execution uses eval methods of ScriptEngine and methods of the Invocable interface.

  2. 绑定Java对象 Binding: This facility allows Java objects to be exposed to script programs as named variables. Bindings and ScriptContext classes are used for this purpose.

  3. 编译 Compilation: This functionality allows the intermediate code generated by the front-end of a script engine to be stored and executed repeatedly. This benefits applications that execute the same script multiple times. These applications can gain efficiency since the engines’ front-ends only need to execute once per script rather than once per script execution. Note that this functionality is optional and script engines may choose not to implement it. Callers need to check for availability of the Compilable interface using an instanceof check.

  4. 调用 Invocation: This functionality allows the reuse of intermediate code generated by a script engine’s front-end. Whereas Compilation allows entire scripts represented by intermediate code to be re-executed, Invocation functionality allows individual procedures/methods in the scripts to be re-executed. As in the case with compilation, not all script engines are required to provide this facility. Caller has to check for Invocable availability.

  5. 脚本引擎和元数据 Script engine discovery and Metadata: Applications written to the Scripting API might have specific requirements on script engines. Some may require a specific scripting language and/or version while others may require a specific implementation engine and/or version. Script engines are packaged in a specified way so that engines can be discovered at runtime and queried for attributes. The Engine discovery mechanism is based on the Service discovery mechanism described in the Jar File Specification. Script engine implementing classes are packaged in jar files that include a text resource named META-INF/services/javax.script.ScriptEngineFactory. This resource must include a line for each ScriptEngineFactory that is packaged in the jar file. ScriptEngineManager includes getEngineFactories method to get all ScriptEngineFactory instances discovered using this mechanism. ScriptEngineFactory has methods to query attributes about script engine.

Summary

六个 interfaces:

  • Bindings
  • Compilable
  • Invocable
  • ScriptContext
  • ScriptEngine
  • ScriptEngineFactory

五个 classes:

  • AbstractScriptEngine
  • CompiledScript
  • ScriptEnginemanager
  • SimpleBindings
  • SimpleScriptContext

一个 exception:

  • ScriptException

JavaScript calls Java method

import javax.script.*;
import java.io.*;

public class ScriptVars {
    public static void main(String[] args) throws Exception {
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("JavaScript");

        // create File object
        File f = new File("test.txt");

        // expose File object as a global variable to the engine
        engine.put("file", f);

        // evaluate JavaScript code and access the variable
        engine.eval("print(file.getAbsolutePath())");
    }
}

Java calls JavaScript functions

import javax.script.*;

public class InvokeScriptFunction {
    public static void main(String[] args) throws Exception {
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("JavaScript");

        // evaluate JavaScript code that defines a function with one parameter
        engine.eval("function hello(name) { print('Hello, ' + name) }");

        // create an Invocable object by casting the script engine object
        Invocable inv = (Invocable) engine;

        // invoke the function named "hello" with "Scripting!" as the argument
        inv.invokeFunction("hello", "Scripting!");
    }
}

Java calls JavaScript object method

import javax.script.*;

public class InvokeScriptMethod {
    public static void main(String[] args) throws Exception {
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("JavaScript");

        // evaluate JavaScript code that defines an object with one method
        engine.eval("var obj = new Object()");
        engine.eval("obj.hello = function(name) { print('Hello, ' + name) }");

        // expose object defined in the script to the Java application
        Object obj = engine.get("obj");

        // create an Invocable object by casting the script engine object
        Invocable inv = (Invocable) engine;

        // invoke the method named "hello" on the object defined in the script
        // with "Script Method!" as the argument
        inv.invokeMethod(obj, "hello", "Script Method!");
    }
}

Translate JavaScript

Rhino JavaScript Engine 会解析 JavaScript 为一棵语法树, 每一个叶子结点都是一个AstNode

AstNode

RhinoClasses

代码如下

public AstRoot parse(String src, int startLineNum)  throws IOException {

        CompilerEnvirons env = new CompilerEnvirons();
        env.setRecoverFromErrors(true);
        env.setGenerateDebugInfo(true);
        env.setRecordingComments(true);

        StringReader strReader = new StringReader(src);

        IRFactory factory = new IRFactory(env);
        return factory.parse(strReader, null, startLineNum);
    }   

接下来, 自己实现接口 org.mozilla.javascript.ast.NodeVisitor, 就可以遍历这棵树, 翻译成你想要的脚本了

Reference

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值