更多详情请见此处
使用 BeanShell 的许多朋友使用它来编写与已经存在的 Java 类或者 API 作业的脚本,或者为了他们自己的应用在运行时在没有其他编译器的帮助下执行其他种类动态的活动。通常这意味着编写相对非结构化的代码——比如,包含在一个 单独的脚本文件或者 eval() 语句里的一系列方法调用或者循环。在之前的章节中我们看到 BeanShell 也具有脚本方法的能力,就像 Java 一样。创建方法以及新的 BeanShell 命令(仅仅是他们自己文件中的方法)是组织你的脚本成为可重用、可维护组件的自然进程。
方 法和结构化的程序设计当然在于对象以及面向对象编程完整的程度。在 Java 中对象是类的产物。虽然 BeanShell 和标准的 Java 语法是兼容的,包括语句、表达式以及方法,但你仍然不能在 BeanShell 中编写新的 Java 类的脚本。但是,BeanShell 允许你编写像“闭合方法”的脚本对象,类似在 Perl 5.x、JavaScript 还有其他对象——可以写脚本的语言中的做法。这类脚本对象(我们马上就会描述)的风格简单而且从脚本方法的风格自然流传下来。你马上会看到这种语法,是标 准 Java 使用“this”引用指向一个对象的概念的直接扩展。
- 注意:
- 在标准 Java 中,一个方法在一个对象(一个实例化的方法)里可以使用专门的变量“this”指向这个封闭
- 的对象。
- // MyClass.java
- MyClass {
- Object getObject() {
- return this; // 返回对象的一个引用
- }
- }
- 在上面的例子里,MyClass 的 getObject() 方法返回自己对象实例(MyClass 对象的实例)的一个引用。
“this”引用
跟多数的语言一样,BeanShell 里的一个执行的方法有它自己持有参数(传值参数)变量和本地声明变量的“本地化”范围。在下面的代码段中,在 foo() 方法中我们会使用到的任何变量通常只在 foo() 当中以及一个特定的 foo() 方法调用的生存期内可见。
示例代码
- // 定义 foo() 方法:
- foo() {
- int bar = 42;
- print( bar );
- }
- // 调用 foo() 方法:
- foo(); // 打印 42
- print( bar ); // Error, bar 在此未定义
运行效果
在上面的例子中,变量"bar"属于方法foo(),因此在方法调用的外面是不可用的——方法退出时变量就会被处理掉,如标准的 Java 本地变量一样。
现在转换一个视角——在 BeanShell 里你可以选择通过专门的“this”引用在一个方法调用退出之后对该作用域“抓住不放”。就像在 Java 中一样,“this”指向当前对象的上下文。唯一不同过的地方就是在这种情况下该上下文只与该方法有关联,却不是一个类的实例。
在方法返回之后保存“this”引用,使用标准 Java 记号“.”你可以继续指向在该方法中定义的变量:
- foo() {
- int bar = 42;
- return this;
- }
- fooObject = foo();
- print( fooObject.bar ); // 打印 42!
运行效果
在上面的例子中,foo() 方法返回值(“this”引用)可以看做是一个“foo”对象的实例。每一次 foo() 方法调用会创建一个新的对象;foo() 此时不仅仅是一个方法,还是对象构造的一种形式。
上面案例中的 foo 对象甚至可以说不是一个对象,说是一个构造器更合适。它包含变量(bar)但没有“行为”。
下一个视角,我们会介绍 BeanShell 方法也允许包含其他方法:
- foo() {
- bar() {
- ...
- }
- }
脚本方法可以通过这种方式定义任意数量的嵌套方法,可以是任意深度的。这些方法是方法的“本地”调用。
BeanShell 方法闭合范围内的语句和表达式可以叫做“本地”方法,就像任何其他方法一样。(局部地定义的方法覆盖外部的——在 Java 里多数方法像本地变量那样隐藏了实例变量。)闭合的方法并不直接在闭合方法外部可见。然而,正如你希望的那样,你可以像对 Java 对象那样通过一个适当的对象引用来调用它们:
- foo() {
- int a = 42;
- bar() {
- print("The bar is open!");
- }
- bar();
- return this;
- }
- // 构造 foo 对象
- fooObject = foo(); // 打印 "the bar is open!"
- // 打印 foo 对象的一个变量
- print ( fooObject.a ); // 42
- // 使用 foo 对象调用一个方法
- fooObject.bar(); // 打印 "the bar is open!"
运行效果
在方法里的方法声明在块状的结构中,表现得就像它们直接被声明在该方法里一样。换言之,没有本地块方法。
示例代码
- foo() {
- bar() { }
- if ( true ) {
- bar2() { }
- }
- return this;
- }
在上面的例子中,方法 bar() 和 bar2() 都被定义在 foo() 里面。
下一章节我们回到变量作用域的话题中来,并更加深入地探讨如何使用脚本方法和对象。
本文转自 tongqiuyan 51CTO博客,原文链接:http://blog.51cto.com/tongqiuyan/757750