动态语言支持

本文是我们名为“ 高级Java ”的学院课程的一部分。

本课程旨在帮助您最有效地使用Java。 它讨论了高级主题,包括对象创建,并发,序列化,反射等。 它将指导您完成Java掌握的过程! 在这里查看 !

目录

1.简介 2.动态语言支持 3.脚本API 4. JVM上JavaScript 5.在JVM上使用Groovy 6. JVM上的Ruby 7. JVM上的Python 8.使用脚本API 9.接下来 10.下载代码

1.简介

在本教程的这一部分中,我们的注意力将完全集中在Java中的脚本和动态语言支持上。 从Java 7开始,JVM就直接支持现代动态语言(也通常称为脚本语言),并且Java 8版本对该空间进行了进一步的增强。

动态语言的优势之一是程序的行为是在运行时定义的,而不是在编译时定义的。 在这些语言中, Ruby ( https://www.ruby-lang.org/en/ ), Python ( https://www.python.org/ )和JavaScript ( http://en.wikipedia.org/wiki/ JavaScript )已广受欢迎,并且是目前使用最广泛的JavaScript 。 我们将研究Java脚本API如何为将这些语言集成到现有Java应用程序中提供一种方法。

2.动态语言支持

众所周知,Java是一种静态类型的语言。 这意味着在编译时可获得类的所有类型化信息,其成员,方法参数和返回值。 使用所有这些详细信息,Java编译器会发出强类型的字节码,然后可以在运行时由JVM有效地解释。

但是,动态语言在运行时而不是编译时执行类型检查。 处理动态语言的挑战是如何实现一个运行时系统,该系统可以选择一种最合适的方法实现,以在程序编译后进行调用。

长期以来,JVM一直没有对动态类型语言的特殊支持。 但是Java 7版本引入了新的invokedynamic指令,该指令使运行时系统(JVM)可以自定义调用站点(调用方法的位置)与方法实现之间的链接。 它确实为在JVM平台上提供有效的动态语言支持和实施打开了一扇门。

3.脚本API

作为2006年发行的Java 6的一部分,新的脚本API已在javax.script包下引入。 该可扩展API旨在插入大多数脚本语言(提供脚本引擎实现)并在JVM平台上运行。

实际上,Java脚本API非常小而且非常简单。 开始使用脚本API的第一步是创建ScriptEngineManager类的新实例。 ScriptEngineManager提供了从正在运行的应用程序类路径中按名称搜索和检索可用脚本引擎的功能。

每个脚本引擎使用各自的ScriptEngine实现表示,并且实质上提供了使用eval()函数家族(具有多个重载版本)执行脚本的能力。 已经有许多流行的脚本(动态)语言提供了对Java脚本API的支持,在本教程的下一部分中,我们将通过玩JavaScriptGroovyRuby / JRubyPython / Jython来了解该API在实践中的效果。 。

4. JVM上JavaScript

我们并非偶然地开始使用JavaScript语言,因为它是Java标准库脚本API支持的最早的脚本语言之一。 而且,从总体上讲,它是每个Web浏览器都能理解的单一编程语言。

eval()函数以最简单的形式执行脚本,并以纯Java字符串的形式传递给脚本。 该脚本没有与评估者(或调用者)共享的状态,并且是独立的代码段。 但是,在典型的实际应用程序中,这种情况非常罕见,并且经常需要将一些变量或属性提供给脚本才能执行一些有意义的计算或操作。 话虽如此,让我们看一个使用简单变量绑定评估真实JavaScript函数调用的简单示例:

final ScriptEngineManager factory = new ScriptEngineManager();
final ScriptEngine engine = factory.getEngineByName( "JavaScript" );final Bindings bindings = engine.createBindings();
bindings.put( "str", "Calling JavaScript" );
bindings.put( "engine", engine );engine.eval( "print(str + ' from ' + engine.getClass().getSimpleName() )", bindings );

执行后,将在控制台上打印以下输出:

Calling JavaScript from RhinoScriptEngine

相当长一段时间以来Rhino一直是JVM上可用的单个JavaScript脚本引擎。 但是Java 8版本带来了一个名为NashornJavaScript脚本引擎的全新实现( http://www.oracle.com/technetwork/articles/java/jf14-nashorn-2126515.html )。

从API的角度来看,并没有太多的区别,但是内部实现却有很大的不同,从而保证了更好的性能。 这是使用Nashorn JavaScript引擎重写的同一示例:

final ScriptEngineManager factory = new ScriptEngineManager();
final ScriptEngine engine = factory.getEngineByName( "Nashorn" );final Bindings bindings = engine.createBindings();
bindings.put( "engine", engine );engine.eval( "print(str + ' from ' + engine.getClass().getSimpleName() )", bindings );

以下输出将打印在控制台上(请注意这次不同的脚本引擎实现):

Calling JavaScript from NashornScriptEngine

尽管如此,我们看过JavaScript代码片段的例子却是微不足道的。 实际上,您可以使用重载的eval()函数调用来评估整个JavaScript文件,并仅在JavaScript中实现相当复杂的算法。 在接下来的部分中,我们将在探索其他脚本语言时看到这些示例。

5.在JVM上使用Groovy

Groovy ( http://groovy.codehaus.org )是JVM平台最成功的动态语言之一。 它通常与Java并行使用,但是它也提供Java脚本API引擎实现,并且可以与JavaScript相似的方式使用。

让我们通过开发一个小的独立脚本,使这个Groovy示例更加有意义和有趣,该脚本在控制台上打印出通过调用Java应用程序与其共享的藏书中每本书的一些详细信息。

Book类非常简单,只有两个属性,author和title:

public class Book {private final String author;private final String title;public Book(final String author, final String title) {this.author = author;this.title = title;}public String getAuthor() {return author;}public String getTitle() {return title;}
}

Groovy脚本(仅命名为script.groovy )使用一些漂亮的语言功能(例如闭包和字符串插值)将书籍属性输出到控制台:

books.each { println "Book '$it.title' is written by $it.author"
}println "Executed by ${engine.getClass().simpleName}"
println "Free memory (bytes): " + Runtime.getRuntime().freeMemory()

现在,让我们使用Java脚本API和预定义的书籍集合(当然,有关Groovy的所有内容)执行这个Groovy脚本:

final ScriptEngineManager factory = new ScriptEngineManager();
final ScriptEngine engine = factory.getEngineByName( "Groovy" );final Collection< Book > books = Arrays.asList(new Book( "Venkat Subramaniam", "Programming Groovy 2" ),new Book( "Ken Kousen", "Making Java Groovy" ));final Bindings bindings = engine.createBindings();
bindings.put( "books", books );
bindings.put( "engine", engine );try( final Reader reader = new InputStreamReader( Book.class.getResourceAsStream("/script.groovy" ) ) ) {engine.eval( reader, bindings );        
}

请注意, Groovy脚本引擎具有对Java标准库的完全访问权限,并且不需要任何附加绑定。 为了确认这一点,上述Groovy脚本的最后一行通过调用Runtime.getRuntime()静态方法访问当前的运行时环境,并打印出可用于运行JVM的可用堆数量(以字节为单位)。 以下示例输出将出现在控制台上:

Book 'Programming Groovy 2' is written by Venkat Subramaniam
Book 'Making Java Groovy' is written by Ken Kousen
Executed by GroovyScriptEngineImpl
Free memory (bytes): 153427528

Groovy推出至今已有10年了。 由于其创新的语言功能(类似于Java语法)以及与现有Java代码的出色互操作性,它很快变得非常流行。 看起来lambdas的引入和Java 8中的Stream API使得Groovy的吸引力降低了一些,但是它仍然被Java开发人员广泛使用。

6. JVM上的Ruby

几年前, Ruby ( https://www.ruby-lang.org/en/ )是用于Web应用程序开发的最流行的动态语言。 尽管如今它的流行程度已逐渐消失,但Ruby及其生态系统在现代Web应用程序开发中带来了许多创新,激发了许多其他编程语言和框架的创建和发展。

JRuby ( http://jruby.org/ )是JVM平台的Ruby编程语言的实现。 与Groovy相似,它还提供了与现有Java代码的出色互操作性,从而保留了Ruby语言语法的美感。

让我们用Ruby语言(名为script.jruby )从JVM上的Groovy脚本部分重写Groovy脚本,并使用Java脚本API对其进行评估。

$books.each do |it| java.lang.System.out.println( "Book '" + it.title + "' is written by " + it.author )
endjava.lang.System.out.println( "Executed by " + $engine.getClass().simpleName )
java.lang.System.out.println( "Free memory (bytes): " +   java.lang.Runtime.getRuntime().freeMemory().to_s )

脚本评估代码基本保持不变,只是脚本引擎和示例书籍集合有所不同,而这一切都与Ruby有关。

final ScriptEngineManager factory = new ScriptEngineManager();
final ScriptEngine engine = factory.getEngineByName( "jruby" );final Collection< Book > books = Arrays.asList(new Book( "Sandi Metz", "Practical Object-Oriented Design in Ruby" ),new Book( "Paolo Perrotta", "Metaprogramming Ruby 2" ));final Bindings bindings = engine.createBindings();
bindings.put( "books", books );
bindings.put( "engine", engine );try( final Reader reader = new InputStreamReader( Book.class.getResourceAsStream("/script.jruby" ) ) ) {engine.eval( reader, bindings );        
}

以下示例输出将出现在控制台上:

Book 'Practical Object-Oriented Design in Ruby' is written by Sandi Metz
Book 'Metaprogramming Ruby 2' is written by Paolo Perrotta
Executed by JRubyEngine
Free memory (bytes): 142717584

从上面的JRuby代码片段中我们可以看出,使用标准Java库中的类有点冗长,并且必须以包名称作为前缀(有一些技巧可以摆脱这一点,但是我们不做这些特定的细节)。

7. JVM上的Python

我们最后一个但并非最不重要的示例将展示JVM平台上的Python ( https://www.python.org/ )语言实现,称为Jython ( http://www.jython.org/ )。

Python语言最近获得了广泛的关注,并且其流行程度每天都在增长。 它被科学界广泛使用,并具有从网络开发到自然语言处理的大量库和框架。

遵循与Ruby相同的路径,我们将使用Python语言(名称为script.py )从JVM部分的Groovy重写示例脚本,并使用Java脚本API对其进行评估。

from java.lang import Runtimefor it in books: print "Book '%s' is written by %s" % (it.title, it.author)print "Executed by " + engine.getClass().simpleName
print "Free memory (bytes): " + str( Runtime.getRuntime().freeMemory() )

让我们实例化Jython脚本引擎,并使用已经熟悉的Java脚本API执行上面的Python脚本。

final ScriptEngineManager factory = new ScriptEngineManager();
final ScriptEngine engine = factory.getEngineByName( "jython" );final Collection< Book > books = Arrays.asList(new Book( "Mark Lutz", "Learning Python" ),new Book( "Jamie Chan", "Learn Python in One Day and Learn It Well" ));final Bindings bindings = engine.createBindings();
bindings.put( "books", books );
bindings.put( "engine", engine );try( final Reader reader = new InputStreamReader( Book.class.getResourceAsStream("/script.py" ) ) ) {engine.eval( reader, bindings );        
}

以下示例输出将在控制台上打印出来:

Book 'Learning Python' is written by Mark Lutz
Book 'Learn Python in One Day and Learn It Well' is written by Jamie Chan
Executed by PyScriptEngine
Free memory (bytes): 132743352

Python作为编程语言的强大之处在于其简单性和陡峭的学习曲线。 随着一群Python开发人员的加入,以某种可扩展性机制将Python脚本语言集成到Java应用程序中的能力听起来像是一个有趣的主意。

8.使用脚本API

Java 脚本API是通过可扩展的脚本支持来丰富Java应用程序的好方法,只需选择您的语言即可。 这也是插入域专用语言 (DSL)的最简单方法,并允许业务专家以最方便的方式表达其意图。

JVM本身的最新更改(请参见“ 动态语言支持”部分)使它成为适用于不同动态(脚本)语言实现的更友好的运行时平台。 毫无疑问,将来会有越来越多的脚本语言引擎可用,这为与新的和现有的Java应用程序无缝集成打开了大门。

9.接下来

从这部分开始,我们实际上是在开始有关Ja​​va作为语言和JVM作为高级运行时执行平台的高级概念的讨论。 在本教程的下一部分中,我们将研究Java Compiler API和Java Compiler Tree API,以学习如何在运行时操作Java源代码。

9.下载代码

这是动态语言支持课程,是高级Java课程的第12部分。 您可以在此处下载源代码: advanced-java-part-12

翻译自: https://www.javacodegeeks.com/2015/09/dynamic-languages-support.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/358098.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

我是如何使用git把本地代码上传到github上的,值得借鉴

背景&#xff1a;最近开发了一套招标系统&#xff0c;我是如何用JSP在网络上架构一个网上招标系统&#xff0c;以推进网站无纸化&#xff0c;过程电子化&#xff0c;管理智能化的发展。 使用git进行上传。 首先自己得有git工具及github账号&#xff0c;自己没有的提前准备一下。…

期中总结

期中总结&#xff1a; 第一章 计算机系统漫游 1.1 Linux基础 1.Linux命令 command [options] [arguments] //中括号代表是可选的&#xff0c;即有些命令不需要选项也不需要参数 选项&#xff08;options&#xff09;或参数&#xff08;arguments&#xff09; 选项是调整命令执…

Kali WPScan的使用(WordPress扫描工具)

一、WPScan简介 WordPress网站介绍 WordPress是全球流行的博客网站&#xff0c;全球有上百万人使用它来搭建博客。他使用PHP脚本和Mysql数据库来搭建网站。 Wordpress作为三大建站模板之一&#xff0c;在全世界范围内有大量的用户&#xff0c;这也导致白帽子都会去跟踪 WordPr…

【jquery系列|Jquery总结篇】包含各种实例,文末有彩蛋!

孙叫兽,前端全栈工程师,微信公众号:电商程序员,如果本文对你有帮助,记得收藏点赞+关注。 jQuery 是一个 JavaScript 库,极大地简化了 JavaScript 编程,很容易学习。(注:本文不演示效果) 简介:jQuery是一个快速、简洁的JavaScript框架,是继Prototype之后又一个优…

文件包含之日志中毒(User-Agent)

目录 一、本地文件包含 二、日志中毒 获取反弹shell获得目标服务器的完全控制权 方法一&#xff1a; 方法二&#xff1a;/var/log/auth.log 一、本地文件包含 本地文件包含漏洞指的是包含本地的php文件&#xff0c;而通过PHP文件包含漏洞入侵网站&#xff0c;可以浏览同服务器所…

对象池回收对象_回收对象以提高性能

对象池回收对象总览 在上一篇文章中&#xff0c;我说过对象反序列化更快的原因是由于使用了回收对象。 由于两个原因&#xff0c;这可能令人惊讶&#xff1a;1&#xff09;相信如今创建对象是如此之快&#xff0c;无关紧要或与回收自己一样快&#xff0c;2&#xff09;默认情况…

由于业务需求,我是如何在需要页面添加悬浮按钮进行切换并添加水印的

背景:APP页面位置有限,列表形式展示,需要做一个悬浮按钮进行切换列表,并给切换的列表添加水印便于区分。 孙叫兽,前端全栈程序员,java程序员,微信公众号:电商程序员 目录 悬浮按钮的实现; 水印功能的实现: 悬浮按钮的实现; body: <!-- 在首页添加一个悬浮按钮…

昆仑镜Kunlun-M使用方法

文章目录 项目介绍和安装测试项目介绍根据Readme.md进行安装扫描测试 实战扫描扫描实战报错1报错2更新项目并重新扫描 扫描结果分析漏洞验证 项目介绍和安装测试 项目介绍 根据Readme.md进行安装 请使用python3.6运行该工具&#xff0c;已停止维护python2.7环境。 安装命…

NOIP前夕:noi.openjudge,Maximum sum

Maximum sum 总Time Limit: 1000msMemory Limit: 65536kB Description Given a set of n integers: A{a1, a2,..., an}, we define a function d(A) as below: t1 t2 d(A) max{ ∑ai ∑aj | 1 < s1 < t1 < s2 < t2 < n } is1 js2 Your task is to calc…

Java EE中的RESTful计时器

在这篇文章中...。 EJB计时器旋风之旅 通过带有示例实现的简单REST接口即时使用EJB计时器 更新&#xff08;2015年7月14日&#xff09; 现在可以在OpenShift上使用该应用程序的前端 。 由于我是前端新手&#xff0c;因此我在其他来源的帮助下组装了此HTML5 AngularJS应用程…

如何查看node的版本及安装的位置?

好多粉丝说我的node版本不支持win7,我把安装包放到了主页QQ群群文件&#xff0c;CSDN资源也有上传。 那么如何查看电脑版本&#xff1f; 电脑快捷键winR&#xff0c;cmd进入黑窗口 node -v 如何查看node安装的位置&#xff1f; where node 如下图所示&#xff1a;

应用安全测试技术DAST、SAST、IAST对比分析

应用安全测试技术DAST、SAST、IAST对比分析-持续更新 版权来源&#xff1a;安全牛首发文章&#xff0c;本文仅补充完善。 一、全球面临软件安全危机 我们即将处于一个软件定义一切的时代&#xff0c;这是 “一个最好的时代&#xff0c;也是一个最坏的时代”。 无论是生活中离不…

android开发之shape详解

很多时候&#xff0c;使用shape能够实现的效果&#xff0c;你用一张图片也能够实现&#xff0c;但问题是一张图片无论你怎么压缩&#xff0c;它都不可能比一个xml文件小&#xff0c;因此&#xff0c;为了获得一个高性能的手机App&#xff0c;我们在开发中应该遵循这样一个原则&…

Fastjson系列漏洞实战和总结

前言 Fastjson是阿里巴巴的开源JSON解析库&#xff0c;它可以解析JSON格式的字符串&#xff0c;支持将Java Bean序列化为JSON字符串&#xff0c;也可以从JSON字符串反序列化到JavaBean。具有执行效率高的特点&#xff0c;应用范围广泛。 目录 Fastjson<1.2.24远程代码执行&a…

我是如何使用laydate日历插件更换掉老项目不好用的日历插件datepicker的

背景:最近整改了一个老项目系统,里面采用的是java+bootstrap+jsp写的,里面的日历插件datepicker特别不好用,容易点击失灵,我决定把它给替换了。 layDate 官网:https://www.layui.com/laydate/ My97DatePicker官网:http://www.my97.net/ 这里简单演示layDate的思路,不展…

用来用去还是觉得SDCMS好用

用来用去还是觉得SDCMS好用 现在可以算是精通了。呵呵&#xff0c;欢迎交流转载于:https://www.cnblogs.com/qiao198/p/4930575.html

spring mvc拦截器_Spring MVC拦截器示例

spring mvc拦截器我认为现在是时候看看Spring的MVC拦截器机制了&#xff0c;这种机制已经存在了很多年&#xff0c;并且是一个非常有用的工具。 Spring Interceptor会按照提示说&#xff1a;在传入的HTTP请求到达您的Spring MVC控制器类之前对其进行拦截&#xff0c;或者相反&a…

Fastjson漏洞

Fastjson概述 Fastjson是阿里巴巴公司开源的一款json解析器&#xff0c;它可以解析 JSON 格式的字符串&#xff0c;支持将 Java Bean 序列化为 JSON 字符串&#xff0c;也可以从 JSON 字符串反序列化到JavaBean。 ➢历史漏洞 Fastjson <1.2.24 反序列化远程命令执行漏洞 Fa…

我是如何用Jquery实现网页缩小放大的

背景:一个比较老的后台系统,客户想操作父窗口的内容,同时查看子窗口,这就需要对页面进行缩小和放大,刚开始领导让我做一个假的隐藏然后缩放,经过测试此法不通,因为这个项目很庞大,框架较老,还有蒙版,使用隐藏hide()属性隐藏后,这个网页就不见了,在N个另一个页面加s…

浅谈哈希表

1. 引言 哈希表&#xff08;Hash Table&#xff09;的应用近两年才在NOI中出现&#xff0c;作为一种高效的数据结构&#xff0c;它正在竞赛中发挥着越来越重要的作用。 哈希表最大的优点&#xff0c;就是把数据的存储和查找消耗的时间大大降低&#xff0c;几乎可以看 成是常数时…