天天看點

深入BeanShell腳本對象

使用 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 對象的執行個體)的一個引用。 

<b>“this”引用</b>

跟多數的語言一樣,BeanShell 裡的一個執行的方法有它自己持有參數(傳值參數)變量和本地聲明變量的“本地化”範圍。在下面的代碼段中,在 foo() 方法中我們會使用到的任何變量通常隻在 foo() 當中以及一個特定的 foo() 方法調用的生存期内可見。

<b>示例代碼</b>

// 定義 foo() 方法: 

foo() { 

int bar = 42; 

print( bar ); 

// 調用 foo() 方法: 

foo(); // 列印 42 

print( bar ); // Error, bar 在此未定義 

<b>運作效果</b>

在上面的例子中,變量"bar"屬于方法foo(),是以在方法調用的外面是不可用的——方法退出時變量就會被處理掉,如标準的 Java 本地變量一樣。

<b>現在轉換一個視角</b>——在 BeanShell 裡你可以選擇通過專門的“this”引用在一個方法調用退出之後對該作用域“抓住不放”。就像在 Java 中一樣,“this”指向目前對象的上下文。唯一不同過的地方就是在這種情況下該上下文隻與該方法有關聯,卻不是一個類的執行個體。

在方法傳回之後儲存“this”引用,使用标準 Java 記号“.”你可以繼續指向在該方法中定義的變量:

return this; 

fooObject = foo(); 

print( fooObject.bar ); // 列印 42! 

<a target="_blank"></a>

在上面的例子中,foo() 方法傳回值(“this”引用)可以看做是一個“foo”對象的執行個體。每一次 foo() 方法調用會建立一個新的對象;foo() 此時不僅僅是一個方法,還是對象構造的一種形式。

上面案例中的 foo 對象甚至可以說不是一個對象,說是一個構造器更合适。它包含變量(bar)但沒有“行為”。

<b>下一個視角</b>,我們會介紹 BeanShell 方法也允許包含其他方法:

    bar() { 

      ... 

    } 

腳本方法可以通過這種方式定義任意數量的嵌套方法,可以是任意深度的。這些方法是方法的“本地”調用。

BeanShell 方法閉合範圍内的語句和表達式可以叫做“本地”方法,就像任何其他方法一樣。(局部地定義的方法覆寫外部的——在 Java 裡多數方法像本地變量那樣隐藏了執行個體變量。)閉合的方法并不直接在閉合方法外部可見。然而,正如你希望的那樣,你可以像對 Java 對象那樣通過一個适當的對象引用來調用它們:

int a = 42; 

bar() { 

print("The bar is open!"); 

bar(); 

// 構造 foo 對象 

fooObject = foo(); // 列印 "the bar is open!" 

// 列印 foo 對象的一個變量 

print ( fooObject.a ); // 42 

// 使用 foo 對象調用一個方法 

fooObject.bar(); // 列印 "the bar is open!" 

在方法裡的方法聲明在塊狀的結構中,表現得就像它們直接被聲明在該方法裡一樣。換言之,沒有本地塊方法。

    bar() { } 

      if ( true ) { 

        bar2() { } 

    return this; 

在上面的例子中,方法 bar() 和 bar2() 都被定義在 foo() 裡面。

下一章節我們回到變量作用域的話題中來,并更加深入地探讨如何使用腳本方法和對象。

本文轉自 tongqiuyan  51CTO部落格,原文連結:http://blog.51cto.com/tongqiuyan/757750