天天看點

BeanShell 簡介與學習(一篇就夠)

簡介:

BeanShell是一種腳本語言,一種完全符合java文法的java腳本語言,并且又擁有自己的一些文法和方法,beanShell是一種松散類型的腳本語言(這點和JS類似)。

下載下傳位址:http://www.beanshell.org

設定環境

l 把;bsh-xx.jar放到$JAVA_HOME/jre/lib/ext檔案夾下

l unix: export CLASSPATH=$CLASSPATH:bsh-xx.jar

l windows: set classpath %classpath%;bsh-xx.jar

運作方式:

l 界面UI方式 :java bsh.Console

l 指令行方式 :java bsh.Interpreter  

l 運作腳本檔案:java bsh.Interpreter filename [ args ]

簡單舉例:

在classpath中設定好環境變量,打開dos視窗,鍵入: java bsh.Console指令

出現BeanShell圖檔代表設定成功,beanshell開始運作

測試内容:

設定變量

foo = "Foo";  

four = (2 + 2)*2/2;

列印變量

print( foo + " = " + four );

循環

for (i=0; i<5 ibr style='font-size:13px;font-style:normal;font-weight:400;color:rgb(204, 204, 204);' />print(i);

在視窗中列印按鈕

button = new JButton( "My Button" );

frame = new JFrame( "My Frame" );

frame.getContentPane().add( button, "Center" );

frame.pack();

frame.setVisible(true);

完整代碼:

foo = "Foo";  

four = (2 + 2)*2/2;

print( foo + " = " + four );  

for (i=0; i<5 ibr style='font-size:13px;font-style:normal;font-weight:400;color:rgb(204, 204, 204);' />print(i);  

button = new JButton( "My Button" );

frame = new JFrame( "My Frame" );

frame.getContentPane().add( button, "Center" );

frame.pack();

frame.setVisible(true);

在視窗中輸入上面的代碼

敲回車執行,運作結果如圖

說明:

因為beanshell是 松散類型的腳本語言是以可以直接寫

foo = "Foo";  

four = (2 + 2)*2/2;

print是beanshell提供一種簡單的列印指令相當于java中的System.out.println()

其他的beanshell腳本指令

· source(), run() – 讀取,或者運作一個腳本檔案

· frame() – 顯示一個視窗

· load(), save() – 讀取或者儲存一個腳本對象到檔案  

· cd(), cat(), dir(), pwd(), etc. 使用Unix下面的指令

· exec() – 運作一個本地的方法

· javap() –使用javap指令.  

· setAccessibility() – 設定可以接收private(私有)和protected(受保護)類型的變量  

BeanShell指令不一定都是内置的腳本指令,腳本方法會自動從classpath中取方法使用,是以你可以 添加你自己的腳本到classpath中來擴充基本的指令

腳本方法

一般的方法:

int addTwoNumbers( int a, int b ) {

return a + b;

}

sum = addTwoNumbers( 5, 7 ); // 12

也可以使用動态的變量類型(無狀态)方法

add( a, b ) {

return a + b;

}

foo = add(1, 2); // 3

foo = add(1, “2”); //”12”   隻要有一個為字元串全部按照字元串處理,系統不會根據1是數字在前把“2”轉換成數字處理(特别注意)

foo = add("Oh", " baby"); // "Oh baby"

實作接口

實作任何接口需要java1.3或者更高

可以使用預設的java匿名類的文法實作一個接口類,例如:

ActionListener scriptedListener = new ActionListener() {

actionPerformed( event ) { ... }

}

不需要實作接口的所有的方法,隻需要實作你使用的方法即可,如果使用你沒有實作的方法,beanshell将抛出一個錯誤,

ml = new MouseListener() {

mousePressed( event ) { ... }

// handle the rest

invoke( name, args ) { print("Method: "+name+" invoked!");

}

腳本對象

使用特殊的 關鍵字this可以建立一個對象(根JS類似)

foo() {

    print("foo");

    x=5;

    bar() {

        print("bar");

    }

    return this;

}

myfoo = foo(); // prints "foo"

print( myfoo.x ); // prints "5"

myfoo.bar(); // prints "bar"

從應用程式中調用BeanShell

建立一個BeanShell的解釋器(interpreter)用 eval()和source()指令可以對一個字元串求值和運作一個腳本檔案

使用set()方法可以給一個對象傳入一個變量的參考

使用get()方法可以重新得到一個變量的結果

完整代碼:

package cn.com.sparknet.util;

import bsh.*;

import java.util.*;

public class BeanShell {

public static void main(String[] args) {

try {

Interpreter interpreter = new Interpreter(); // 構造一個解釋器

interpreter.set("foo", 5); // 設定變量

interpreter.set("date", new Date()); //設定一個時間對象

Date date = (Date) interpreter.get("date"); // 重新得到時間變量

interpreter.println(date.toString()); //列印時間變量

interpreter.eval("bar = foo*10"); // 對一段腳本求值,并得到結果

System.out.println(interpreter.get("bar")); //列印變量

interpreter.source("d:\\helloWorld.bsh"); // 導入并執行一個腳本檔案

}

catch (Exception e) {

//如果發生異常,寫入日志檔案

Log.error(new BeanShell(), "main", FormatDate.getCurrDate(), e.getMessage());

}

}

}

BeanShell文法

BeanShell是一種最原始的java解釋器。

标準的java文法

// Use a hashtable

Hashtable hashtable = new Hashtable();

Date date = new Date();

hashtable.put( "today", date );

// Print the current clock value

print( System.currentTimeMillis() );

// Loop

for (int i=0; i<5 ibr style='font-size:13px;font-style:normal;font-weight:400;color:rgb(204, 204, 204);' />print(i);

// Pop up a frame with a button in it

JButton button = new JButton( "My Button" );

JFrame frame = new JFrame( "My Frame" );

frame.getContentPane().add( button, "Center" );

frame.pack();

frame.setVisible(true);

松散類型的java文法

// Use a hashtable

hashtable = new Hashtable();

date = new Date();

hashtable.put( "today", date );

// Print the current clock value

print( System.currentTimeMillis() );

// Loop

for (i=0; i<5 ibr style='font-size:13px;font-style:normal;font-weight:400;color:rgb(204, 204, 204);' />print(i);

// Pop up a frame with a button in it

button = new JButton( "My Button" );

frame = new JFrame( "My Frame" );

frame.getContentPane().add( button, "Center" );

frame.pack();

frame.setVisible(true);

異常處理

标準的java異常

try {

int i = 1/0;

} catch ( ArithmeticException e ) {

print( e );

}

松散的異常處理(類似JS)

try {

...

} catch ( e ) {  

...

}

松散類型變量的作用範圍

标準的java程式的變量作用範圍是在一個子產品中的(在子產品中聲明的變量),而 在松散類型的語言中如果在一個子產品中沒有指定一個變量的類型,則認為是一個全局變量(隻有它以後的代碼可以使用該變量,系統在調用該變量的時候自動生成一個全局變量,也就為什麼在調用子產品之前不能使用該變量的原因)

// Arbitrary code block

{

y = 2; // Untyped variable assigned

int x = 1; // Typed variable assigned

}

print( y ); // 2

print( x ); // Error! x is undefined.

// Same with any block statement: if, while, try/catch, etc.

if ( true ) {

y = 2; // Untyped variable assigned

int x = 1; // Typed variable assigned

}

print( y ); // 2

print( x ); // Error! x is undefined.

同樣也使用于for-loop, if-else等循環語句

for( int i=0; i<10 i typed for-init variablebr style='font-size:13px;font-style:normal;font-weight:400;color:rgb(204, 204, 204);' />j=42;

}

print( i ); // Error! 'i' is undefined.

print( j ); // 42

for( z=0; z<10 z untyped for-init variablebr style='font-size:13px;font-style:normal;font-weight:400;color:rgb(204, 204, 204);' />print( z ); // 10

友善靈活的文法

标準的java文法

java.awt.Button button = new java.awt.Button();

button.setLabel(“javaButton”);

松散的文法

button = new java.awt.Button();

button.label = "my button";

你也可以使用{}來對一個對象設定屬性

b = new java.awt.Button();

b{"label"} = "my button"; // Equivalent to: b.setLabel("my button");

h = new Hashtable();

h{"foo"} = "bar"; // Equivalent to: h.put("foo", "bar");

自動裝箱和自動拆箱(box和unbox)

BeanShell自動轉為簡單類型

i=5;

iw=new Integer(5);

print( i * iw ); // 25

導入類和包

import javax.xml.parsers.*;

import mypackage.MyClass;

超級導入法:

import *;

BeanShell預設導入下面的包

· java.lang  

· java.io  

· java.util  

· java.net  

· java.awt  

· java.awt.event  

· javax.swing  

· javax.swing.event  

友好文檔實體

BeanShell支援特殊的文檔操作類型内容

@gt > @lt <

@lteq < gteq >=

@or || @and &&

@bitwise_and & @bitwise_or |

@left_shift << right_shift >>

@right_unsigned_shift >>> @and_assign &=

@or_assign |= @left_shift_assign << br style='font-size:13px;font-style:normal;font-weight:400;color:rgb(204, 204, 204);' />@right_shift_assign >>= @right_unsigned_shift_assign >>>=

腳本方法

你可以定義方法象java中的定義方法一樣

int addTwoNumbers( int a, int b ) {

return a + b;

}

你可以使用内餡的BeanShell方法使用他們

sum = addTwoNumbers( 5, 7 );

隻有BeanShell變量可以被動态定義為動态類型,方法可以有動态的參數以及傳回類型

add( a, b ) {

return a + b;

}

在這個方法中,BeanShell将 動态的決定類型當這個方法被調用時并且能夠準确的計算出你想要的結果

foo = add(1, 2);

print( foo ); // 3

foo = add("Oh", " baby");

print( foo ); // Oh baby

在第一個例子中BeanShell将把參數定義為數字型,并傳回數字型

在第二個例子中BeanShell将把參數定義為字元型,并傳回字元對象

變量和方法的可見範圍

就像您所預期的那樣, 在方法内您可以參考到上下文中上面的變量和方法

a = 42;

someMethod() { ... }

foo() {

print( a );

someMethod(); // invoke someMethod()

}

// invoke foo()

foo(); // prints 42

如果一個變量隻有在方法内使用請定義成局部變量,即加上類型,如果是全局變量請在方法外定義

var = "global";

foo() {

print(var);

String var = "local";

print(var);

}

foo();

print(var);

将列印出

global

local

global

方法内的var(第四行)變量屬于局部變量,不會覆寫全局變量var(第一行)的是以改變var(第四行)變量不會影響到全局變量var(第一行)

範圍參考:super

使用super關鍵字可以在局部參考到全局變量

var = "global";

foo() {

String var = "local";

print(var);

print(super.var);

}

foo();

将輸出

local

global

腳本對象

this對象

在java标準語言中可以使用this傳回一個類的一個執行個體

// MyClass.java

MyClass {

Object getObject() {

return this; // return a reference to our object

}

}

在這個例子中getObject() 方法是傳回MyClass類的一個執行個體

在BeanShell中對象中的變量隻是局部的變量在對象内可以使用,在對象外是不可以使用(不同于前面for-loop,if-else中的使用);

// Define the foo() method:

foo() {

bar = 42;

print( bar );

}  

// Invoke the foo() method:

foo(); // prints 42

print( bar ); // Error, bar is undefined here  

可以使用this傳回對象,使用對象加上“.”運算符參考屬性(類似JS)

foo() {

bar = 42;

return this;

}

fooObj = foo();

print( fooObj.bar ); // prints 42!

同樣對象中也可以定義一些方法

foo() {

bar() {

...

}

}

例如

foo() {

int a = 42;

bar() {

print("The bar is open!");

}

bar();

return this;

}

// Construct the foo object

fooObj = foo(); // prints "the bar is open!"

// Print a variable of the foo object

print ( fooObj.a ) // 42

// Invoke a method on the foo object

fooObj.bar(); // prints "the bar is open!"

也可以把bar()和foo也可以代參數

foo() {

return this;

}

bar(int a) {

print("The bar is open!" + a);

}

foo().bar(1);

也可以把bar()方法定義到對象外面

foo() {

bar(int a) {

print("The bar is open!" + a);

}

return this;

}

foo().bar(1);

BeanShell一種松散的腳本語言,有很多中聲明的方法可以使用

This super global

This是參考目前對象

Super是參考父親對象

Global是參考最上層對象

super.super.super...foo = 42; // Chain super. to reach the top

global.foo = 42;  

簡單例子:

文本拖動:

dragText() {

f = new Frame("Drag in the box");

f.setFont( new Font("Serif", Font.BOLD, 24) );

f.setSize(300, 300);

f.show();

gc = f.getGraphics();

gc.setColor(Color.cyan);

mouseDragged( e ) {

gc.drawString("Drag Me!", e.getX(), e.getY());

}

mouseMoved( e ) { }

f.addMouseMotionListener( this );

}

簡單畫圖

import bsh.util.BshCanvas; // BshCanvas simply buffers graphics

graph( int width, int height ) {

canvas=new BshCanvas();  

canvas.setSize( width, height );

frame=frame( canvas );

graphics=canvas.getBufferedGraphics();

// draw axis

graphics.setColor( Color.red );

graphics.drawLine( 0, height/2, width, height/2 );

graphics.drawLine( width/2, 0, width/2, height );

graphics.setColor( Color.black );

plot(int x, int y) {

graphics.fillOval( (x+width/2-1), (y+height/2-1), 3, 3);

canvas.repaint();

}

return this;

}

drawSin( graph ) {

for (int x=-100; x<100 x br style='font-size:13px;font-style:normal;font-weight:400;color:rgb(204, 204, 204);' />y=(int)(50*Math.sin( x/10.0 ));

graph.plot( x, y );

}

}

簡單web浏覽器

import javax.swing.*;

import javax.swing.event.*;

import javax.swing.text.*;

import java.awt.event.*;

import java.awt.*;

JFrame browser( startingUrl ) {

invoke( method, args ) {}

windowClosing(WindowEvent we) {

we.getWindow().setVisible(false);

}

setPage( url ) {

try {

pane.setPage( url );

} catch(Exception e) {

statusBar.setText("Error opening page: "+url);

}

}

hyperlinkUpdate( HyperlinkEvent he ) {

type = he.getEventType();

if (type == HyperlinkEvent.EventType.ENTERED) {

pane.setCursor(

Cursor.getPredefinedCursor( Cursor.HAND_CURSOR) );

statusBar.setText(he.getURL().toString());

} else  

if (type == HyperlinkEvent.EventType.EXITED) {

pane.setCursor( Cursor.getDefaultCursor() );

statusBar.setText(" ");

} else {

setPage( he.getURL() );

if (urlField != null)

urlField.setText(he.getURL().toString());

}

}

frame = new JFrame("Browser");

frame.setSize(400,300);

frame.addWindowListener( this );

urlPanel = new JPanel();

urlPanel.setLayout(new BorderLayout());

urlField = new JTextField(startingUrl);

urlPanel.add(new JLabel("Site: "), BorderLayout.WEST);

urlPanel.add(urlField, BorderLayout.CENTER);

statusBar = new JLabel(" ");

pane = new JEditorPane();

pane.setEditable(false);

setPage( startingUrl );

jsp = new JScrollPane(pane);  

frame.getContentPane().add(jsp, BorderLayout.CENTER);

frame.getContentPane().add(urlPanel, BorderLayout.SOUTH);

frame.getContentPane().add(statusBar, BorderLayout.NORTH);

// This is the equivalent of an inner class in bsh.

urlTextHandler() {

actionPerformed(ActionEvent ae) {

setPage( ae.getActionCommand() );

}

return this;

}

urlField.addActionListener( urlTextHandler() );

pane.addHyperlinkListener( (HyperlinkListener)this );

return frame;

}

browser = browser("http://java.sun.com/");

browser.show();

繼續閱讀