JDK1.7新特性(3):java语言动态性之脚本语言API

简介: 简要描述:其实在jdk1.6中就引入了支持脚本语言的API。这使得java能够很轻松的调用其他脚本语言。具体API的使用参考下面的代码: 1 package com.rampage.jdk7.

简要描述:其实在jdk1.6中就引入了支持脚本语言的API。这使得java能够很轻松的调用其他脚本语言。具体API的使用参考下面的代码:

  1 package com.rampage.jdk7.chapter2;
  2 
  3 import java.io.FileWriter;
  4 import java.io.IOException;
  5 
  6 import javax.script.Bindings;
  7 import javax.script.Compilable;
  8 import javax.script.CompiledScript;
  9 import javax.script.Invocable;
 10 import javax.script.ScriptContext;
 11 import javax.script.ScriptEngine;
 12 import javax.script.ScriptEngineManager;
 13 import javax.script.ScriptException;
 14 import javax.script.SimpleBindings;
 15 
 16 /**
 17  * 简单的脚本引擎使用方法
 18  * 
 19  * @author zyq
 20  *
 21  */
 22 public class SimpleScriptAPI {
 23     public static void main(String[] args) throws ScriptException, IOException, NoSuchMethodException {
 24         SimpleScriptAPI simpleScriptEngine = new SimpleScriptAPI();
 25         
 26         // Part 1: 通用的脚本引擎用法
 27         ScriptEngine engine = simpleScriptEngine.getJavaScriptEngine();
 28         if (engine == null) {
 29             throw new RuntimeException("找不到JavaScript脚本执行引擎!");
 30         }
 31         engine.eval("var a = 12;");
 32         
 33         // Part 2: 不同脚本语言与java之间的对象绑定
 34         engine.put("name", "Alex");
 35         engine.eval("var message = 'hello ' + name");
 36         Object message = engine.get("message");
 37         System.out.println(message);         // hello Alex
 38         
 39         // 当然也可以通过SimpleBinds对象来进行变量绑定或者通过脚本引擎的createBindings方法
 40         Bindings bindings = new SimpleBindings();
 41         bindings = engine.createBindings();
 42         bindings.put("hobby1", "java");
 43         bindings.put("hobby2", "dota");
 44         engine.eval("var message2 = 'I like ' + hobby1 + ' and ' + hobby2", bindings);
 45         // 使用binding来绑定的变量只能在脚本语言内部是使用,java语言内获取不到对应的变量
 46         System.out.println(engine.get("message2"));        // null 
 47         System.out.println(engine.get("hobby1"));        // null
 48         System.out.println(engine.get("hobby2"));        // null
 49         engine.put("hobby1", "java");
 50         engine.put("hobby2", "dota");
 51         engine.eval("var message2 = 'I like ' + hobby1 + ' and ' + hobby2"); 
 52         System.out.println(engine.get("message2"));   // I like java and dota
 53         System.out.println(engine.get("hobby1"));      // java
 54         System.out.println(engine.get("hobby2"));      // dota
 55         
 56         // Part 3: 脚本执行上下文
 57         // ScriptContext的setReader/setWriter/setErrorWriter可以分别设置脚本执行时候的输入来源,输出目的地和错误输出目的地
 58         ScriptContext context = engine.getContext();
 59         context.setWriter(new FileWriter("output.txt"));
 60         engine.eval("var a = 13");
 61         // ScriptContext中也有setAttribute和getAttribute方法来自定义属性。属性有不同的作用域之分。
 62         // 每个作用域都以一个对应的整数表示其查找顺序,该整数越小,说明查找时的顺序更优先。
 63         // 因此在设置属性时需显示的指定所在的作用域,在获取属性的时候可以指定查找的作用域。也可以选择根据作用域优先级
 64         // 自动进行查找。
 65         // 但是脚本执行上下文所能包含的作用域可以通过 getScopes 方法得到而不能随意指定
 66         System.out.println(context.getScopes());        // [100, 200]
 67         // ScriptContext预先定义了两个作用域: ENGINE_SCOPE(当前脚本引擎) 和 GLOBAL_SCOPE(从同一引擎工厂创建出来的所有脚本引擎),前者的优先级更高
 68         context.setAttribute("name", "Alex", ScriptContext.GLOBAL_SCOPE);
 69         context.setAttribute("name", "Bob", ScriptContext.ENGINE_SCOPE);
 70         System.out.println(context.getAttribute("name"));        // Bob
 71         // ScriptContext的setbindings方法设置的语言绑定对象会影响到ScriptEngine在执行脚本时的变量解析。
 72         // ScriptEngine的put和get方法所操作的实际上就是ScriptContext中作用域为ENGINE_SCOPE的语言绑定对象。
 73         // 从ScriptContext中得到语言绑定对象之后,可以直接对这个对象进行操作。如果在ScriptEngine的eval中没有
 74         // 指明所使用的语言绑定对象,实际上起作用的是ScriptContext中作用域为ENGINE_SCOPE的语言绑定对象。
 75         Bindings binding1 = engine.createBindings();
 76         binding1.put("name", "Alex");
 77         context.setBindings(binding1, ScriptContext.GLOBAL_SCOPE);
 78         Bindings binding2 = engine.createBindings();
 79         binding2.put("name", "Bob2");
 80         context.setBindings(binding2, ScriptContext.ENGINE_SCOPE);
 81         System.out.println(engine.get("name"));        // Bob2
 82         Bindings binding3 = context.getBindings(ScriptContext.ENGINE_SCOPE);
 83         binding3.put("name", "Alex2");
 84         System.out.println(engine.get("name"));        // Alex2
 85         context.setAttribute("name", "Bob3", ScriptContext.ENGINE_SCOPE);
 86         System.out.println(engine.get("name"));        // Bob3
 87         
 88         // Part 4: 脚本的编译
 89         // 脚本语言一般是解释执行的,脚本引擎在运行时需要先解析脚本之后再执行。一般来说
 90         // 通过解释执行的方式运行脚本的速度比先编译再运行会慢一些。所以对于需要多次执行的脚本,我们
 91         // 可以选择先编译,以防止重复解析。不是所有的脚本语言都支持对脚本进行编译,如果脚本支持
 92         // 编译,他会实现 javax.script.Compilable接口。编译的结果用CompiledScript来表示。
 93         if (engine instanceof Compilable) {
 94             CompiledScript script  = ((Compilable) engine).compile("var a = 12; b = a * 3;");
 95             script.eval();
 96         }
 97         
 98         // Part 5: 方法调用
 99         // 有些脚本引擎允许使用者单独调用脚本中的某个方法。支持这种调用方法的脚本引擎可以实现
100         // javax.script.Invocable 接口。通过Invocable接口既可以调用脚本中的顶层方法,也可一
101         // 调用对象中的成员方法。如果脚本中的顶层方法或者对象中的成员方法实现了java中的接口,
102         // 可以通过Invocable接口中的方法来获取及脚本中对应的java接口 的实现对象。这样就可以
103         // 在java中定义借口,在脚本中实现接口。程序中使用该接口的其他部分代码并不知道接口是
104         // 由脚本来实现的。
105         String scriptText = "function greet(name) {return 'hello ' + name; }";
106         engine.eval(scriptText);
107         Invocable invocable = (Invocable) engine;
108         System.out.println(invocable.invokeFunction("greet", "Alex"));  // hello Alex
109         // 如果调用的是脚本中对象的成员方法,则需要用invokeMethod.
110         scriptText = "var obj = {getGreeting: function(name) {return 'hello ' + name;}};";
111         engine.eval(scriptText);
112         Object scope = engine.get("obj");
113         System.out.println(invocable.invokeMethod(scope, "getGreeting", "Bob"));  // hello Bob
114         // 在脚本中实现接口
115         scriptText = "function getGreeting(name) {return 'Hello ' + name;}";
116         engine.eval(scriptText);
117         Greet greet = invocable.getInterface(Greet.class);        // 接口必须是public类型的
118         System.out.println(greet.getGreeting("KiDe"));
119     }
120 
121     private ScriptEngine getJavaScriptEngine() {
122         ScriptEngineManager manager = new ScriptEngineManager();
123         // PS: 通过脚本引擎管理者来获取对应引擎,有三种方法:一是通过getEngineByName(这时只能是 javascript 或者
124         // JavaScript)
125         ScriptEngine engine = manager.getEngineByName("JavaScript");
126         // 第二种方法是通过 getEngineByExtension (这时候只能是全小写的js)
127         // engine = manager.getEngineByExtension("js");
128         // 第三种方法是通过 getEngineByMimeType (这时候也必须是全小写的 text/javascript)
129         // engine = manager.getEngineByMimeType("text/javascript");
130         
131         return engine;
132     }
133 }
SimpleScriptAPI
1 package com.rampage.jdk7.chapter2;
2 
3 public interface Greet {
4     String getGreeting(String name);
5 }
Greet

 

黎明前最黑暗,成功前最绝望!
相关文章
|
21天前
|
数据采集 分布式计算 大数据
Java语言在大数据处理中的应用
传统的大数据处理往往依赖于庞大的数据中心和高性能的服务器,然而随着大数据时代的到来,Java作为一种强大的编程语言正在被广泛应用于大数据处理领域。本文将探讨Java语言在大数据处理中的优势和应用,以及其在分布式计算、数据处理和系统集成等方面的重要作用。
|
1天前
|
安全 Java API
RESTful API设计与实现:Java后台开发指南
【4月更文挑战第15天】本文介绍了如何使用Java开发RESTful API,重点是Spring Boot框架和Spring MVC。遵循无状态、统一接口、资源标识和JSON数据格式的设计原则,通过创建控制器处理HTTP请求,如示例中的用户管理操作。此外,文章还提及数据绑定、验证、异常处理和跨域支持。最后,提出了版本控制、安全性、文档测试以及限流和缓存的最佳实践,以确保API的稳定、安全和高效。
|
2天前
|
Java Android开发 C++
Kotlin vs Java:选择最佳语言进行安卓开发
【4月更文挑战第13天】Java曾是安卓开发的主流语言,但Kotlin的崛起改变了这一局面。Google在2017年支持Kotlin,引发两者优劣讨论。Java以其成熟稳定、强大生态和跨平台能力占优,但代码冗长、开发效率低和语言特性过时是短板。Kotlin则以简洁语法、空安全设计和高度兼容Java脱颖而出,但社区和生态系统仍在发展中,可能存在学习曲线和性能问题。选择语言应考虑项目需求、团队熟悉度、维护性、性能和生态系统。无论选择哪种,理解其差异并适应新技术至关重要。
|
3天前
|
存储 Java 关系型数据库
掌握Java 8 Stream API的艺术:详解流式编程(一)
掌握Java 8 Stream API的艺术:详解流式编程
19 1
|
13天前
|
前端开发 Java API
构建RESTful API:Java中的RESTful服务开发
【4月更文挑战第3天】本文介绍了在Java环境中构建RESTful API的重要性及方法。遵循REST原则,利用HTTP方法处理资源,实现CRUD操作。在Java中,常用框架如Spring MVC简化了RESTful服务开发,包括定义资源、设计表示层、实现CRUD、考虑安全性、文档和测试。通过Spring MVC示例展示了创建RESTful服务的步骤,强调了其在现代Web服务开发中的关键角色,有助于提升互操作性和用户体验。
构建RESTful API:Java中的RESTful服务开发
|
13天前
|
Java
Java语言打印九九乘法表(详解)
Java语言打印九九乘法表(详解)
12 1
Java语言打印九九乘法表(详解)
|
21天前
|
Java API 开发工具
【软件设计师备考 专题 】C、C++、Java、Visual Basic、Visual C++等语言的基础知识和应用(三)
【软件设计师备考 专题 】C、C++、Java、Visual Basic、Visual C++等语言的基础知识和应用
30 0
|
21天前
|
Java 数据处理 数据库
【软件设计师备考 专题 】C、C++、Java、Visual Basic、Visual C++等语言的基础知识和应用(二)
【软件设计师备考 专题 】C、C++、Java、Visual Basic、Visual C++等语言的基础知识和应用
33 0
|
21天前
|
存储 算法 Java
【软件设计师备考 专题 】C、C++、Java、Visual Basic、Visual C++等语言的基础知识和应用(一)
【软件设计师备考 专题 】C、C++、Java、Visual Basic、Visual C++等语言的基础知识和应用
33 0
|
22天前
|
Java 数据库连接 API
Java 学习路线:基础知识、数据类型、条件语句、函数、循环、异常处理、数据结构、面向对象编程、包、文件和 API
Java 是一种广泛使用的、面向对象的编程语言,始于1995年,以其跨平台性、安全性和可靠性著称,应用于从移动设备到数据中心的各种场景。基础概念包括变量(如局部、实例和静态变量)、数据类型(原始和非原始)、条件语句(if、else、switch等)、函数、循环、异常处理、数据结构(如数组、链表)和面向对象编程(类、接口、继承等)。深入学习还包括包、内存管理、集合框架、序列化、网络套接字、泛型、流、JVM、垃圾回收和线程。构建工具如Gradle、Maven和Ant简化了开发流程,Web框架如Spring和Spring Boot支持Web应用开发。ORM工具如JPA、Hibernate处理对象与数
88 3