科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道如何在Java平台上使用脚本语言做Java开发(1)

如何在Java平台上使用脚本语言做Java开发(1)

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

本篇文章概括了一些脚本语言(如Groovy,Jruby,Jython)和Java语言的区别,论述了一些在Java平台上使用脚本将会面临的挑战。同时,本文介绍了一些方法,使你可以集成一些最初由Ruby或Python写成的脚本到你的Java代码中。

作者:Gregor Roth/梁婷婷 编译 来源:51CTO.com 2007年12月10日

关键字:

  • 评论
  • 分享微博
  • 分享邮件

在本页阅读全文(共4页)

从脚本中调用Java类

在脚本中引用Java类需要在使用前引入(import)Java类。例如,JRuby定义了一个特殊语句“include Java”来访问Java runtime中内置的Java类。其他非绑定的类引用时需要加前缀“Java ::”,可以参看列表7,JRuby脚本的前几条语句激活了Java支持,定义了常量来代表SSLContext类和BlockingConnection类的路径。

与JRuby相比,脚本runtimes如Jython使用现有的、本身的脚本语句来引入Java类。如Python模块,可以使用普通的Python语句“import<packagename>”引入Java包。Jython还支持Python的不同形式的import语句,如“from <packagename> import <class>”。Groovy,是明确地被设计成运行在Java平台的,它使用Java的import语法。

紧凑的语法意味着代码量的减少

脚本语言的语法要比Java的语法紧凑的多。如,不管是Groovy,Ruby还是Python,都不需要你写冗长的getters和setters(属性设置)。为了简化JavaBeans属性操作,这些脚本语言的Java runtime允许用直接的、类似脚本的方式使用这些属性。

一个Java方法,如<object>.getDefault()可以被写成<object>.default。而且,JRuby runtime会自动把Java的CamelCase(骆驼拼写法)的命名形式匹配为Ruby的形式。如,你可能会这样写一个Java方法:<object>.activateSecureMode(),在JRuby中就变成了<object>.activate_secured_node()。

基于这样的特征,Java类看起来就像是普通的脚本类,参看列表7。这个例子是在Jruby中使用Java的网络类库来实现一个SMTP客户端。

列表7:在JRuby中使用Java类库(实现一个SMTP客户端)

include Java
# set up constants to shorten the paths
SSLContext = javax.net.ssl.SSLContext
BlockingConnection = Java::org.xsocket.stream.BlockingConnection

#performs new BlockingConnection(String, int, SSLContext.getDefault(), boolean)
bc = BlockingConnection.new('smtp.web.de', 25, SSLContext::default, false)
bc.receive_timeout_millis = 60 * 1000 # performs setReceiveTimeoutMillis(long)
puts bc.read_string_by_delimiter("\r\n") # performs readStringByDelimiter(String)
bc.write("STARTTLS\r\n")  
puts bc.read_string_by_delimiter("\r\n")
bc.activate_secured_mode()
bc.write('AUTH PLAIN ' + ["\000" + 'from.me' + "\000" + 'myPassword'].pack('m'))
puts bc.read_string_by_delimiter("\r\n")
bc.write("HELO Server\r\n")
puts bc.read_string_by_delimiter("\r\n")
bc.write("MAIL FROM: from.me@web.de\r\n")
puts bc.read_string_by_delimiter("\r\n")
bc.write("RCPT TO: itsyou@gmx.net\r\n")
puts bc.read_string_by_delimiter("\r\n")
bc.write("data\r\n")
puts bc.read_string_by_delimiter("\r\n")
mail =
'Message-ID: 46D957AF.2020804
Date: Sat, 01 Sep 2007 14:14:39 +0200
From: from.me@web.de
User-Agent: my mail client
MIME-Version: 1.0
To: itsyou@gmx.net
Subject: what I have to say
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Content-Transfer-Encoding: 7bit
combining scripting languages with Java is great'
bc.write("#{mail}\r\n.\r\n")
puts bc.read_string_by_delimiter("\r\n")
bc.write("quit\r\n")
puts bc.read_string_by_delimiter("\r\n")
bc.close()

在Java虚拟机上运行脚本语言可以让你无缝结合Java代码和脚本。通过调用一个嵌入的Java对象的方法,脚本runtime寻找Java类库的一个恰当的方法特征。通过识别一个匹配的Java方法,runtime执行这个方法调用。针对脚本的参数的数据类型自动转化成适合的Java类型。

调用重载的Java方法

就像前面提到的,动态类型语言不需要类型声明。这样也存在不便之处,一个隐藏的陷阱就是调用重载的Java方法。当调用一个重载的Java方法的时候,脚本runtime需要选择合适的方法。某些情况下,选择的方法实现并不是所期望的,参看下面两个例子。

列表8给出了一个重载的Java类。

列表8:一个重载的Java类

package test;
public class NonBlockingConnection  {
public void write(int i) {
System.out.println("writing int " + i);
}
public void write(long l) {
System.out.println("writing long " + l);
}
}

列表9给出了Jython如何调用这些重载方法

列表9:使用Juthon调用重载方法

from java.lang import Integer
from test import NonBlockingConnection
# call 1 
NonBlockingConnection().write(214748364700) # call method based on python built-in data type
# prints out:
# writing long 214748364700
# call 2
NonBlockingConnection().write(55) # call method based on python built-in data type
# prints out:
# writing long 55
# ups, not int?
# call 3
NonBlockingConnection().write(Integer(55))
# pass over a Java object instead of python data type
# prints out:
# writing int 55

Jython脚本的Call 2部分并没有完成期望的int类型的Java方法的调用。一个用来确定调用哪个重载方法的比较实用的方法是,在脚本中实例化需要的Java数据类型的对象,用它代替脚本内的类型。当你使用Groovy时,方法重载根本不是问题,因为Groovy同时支持静态和动态类型。

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章