深入浅出Rhino:Java与JS互操作(1)(2)
JavaScript操纵Java对象
1. Rhino如何访问Java包与类文件
Java语法规定,任何代码都必须以class文件的形式存在,而每个class文件必须属于一个package,默认为default。而JavaScript并没有类似package的层级结构概念,那么如何使用Rhino访问Java类文件呢?
Rhino定义了一个top-level变量Packages。变量Packages对应的所有属性均对应Java包名。比如,我们需要访问某一个Java的Package com.example.
- js> Packages.com.example
- [JavaPackage com.example]
简单起见,我们也可以去掉变量Packages,直接输入Java包名。因此,上述Package com.example等价与com.example,如下:
- js> com.example
- [JavaPackage com.example]
刚才演示了如何通过js shell访问Java包,访问Java类的方式类似。假如我们需要访问标准的Java 文件类java.io.File,如下。
- js> java.io.File
- [JavaClass java.io.File]
或者,为避免输入全名,我们先导入包,然后输入Class类名,如下:
- js> importPackage(java.io)
- js> File
- [JavaClass java.io.File]
这里的importPackage(java.io),在效果上等价于Java声明import java.io.*; 不同的是,Java会隐式import java.lang.*,而Rhino不会。因为Rhino定义的对象Boolean, Math, Number, Object, String等与Java语法完全不同,两者无法等价。
这里需要注意的是,Rhino对该语法的错误处理机制,当被访问的类存在时,Rhino加载该class,而当其不存在时,则把它当成package名称,而并不会报错。例如,当访问一个不存在的类com.example.AAA时,输入如下。
- js> com.example.AAA
- [JavaPackage com.example.AAA]
仅当访问类AAA时,Rhino才会报错。
2. Rhino如何与Java对象交互
与Java类似,Rhino使用new操作符创建对象。
- js> new java.util.Date()
- Thu Nov 03 16:19:04 CST 2011
可以使用JavaScript变量存储Java对象,并调用其方法,如下:
- js> f = new java.io.File("sample.txt")
- sample.txt
- js> f.isDirectory()
- false
对于static方法与变量,调用如下:
- js> java.lang.Math.PI
3.141592653589793
- js> java.lang.Math.cos(0)
1
在JavaScript中,方法本身就是对象,这一点与Java不同。我们可以通过下列方式查看方法的重载:
- js> f.listFiles
- function listFiles() {/*
- java.io.File[] listFiles()
- java.io.File[] listFiles(java.io.FilenameFilter)
- java.io.File[] listFiles(java.io.FileFilter)
- */}
输出中列出三个重载方法。第一个为无参函数,第二与第三个对应的参数分别为FilenameFilter与FileFilter。
另一个比较有意思的特点是通过构造for..in,查看对象对应的所有方法与变量。如下:
- js> for (i in f) { print(i) }
- exists
- parentFile
- mkdir
- toString
- wait
- [44 others]
这里列出的方法一部分来自于父类,比如wait来自父类java.lang.Object。
对于JavaBean,Rhino也提供按名字访问的简单方式。比如,通过下面这种方式,我们就可以调用File对象的getName与isDirectory方法:
- js> f.name
- test.txt
- js> f.directory
- false