快速入門
歡迎使用BeanShell.這是一個速成課程。我們將省去一些重要的選項和細節。要學習更多的內容請看本User's Guide的其它部分。
下載和運行BeanShell
請到http://www.beanshell.org下載最新的JAR文件。你可以用圖形桌面模式和命令行模式起動BeanShell。
如果你只是要玩一玩BeanShell,你可以在BeanShell的jar文件上雙擊來起動BeanShell的桌面。但不管怎樣,如果你要讓BeanShell與你的類與應用程序一起工作就必須將BeanShell的jar文件加到classpath中。
你可以將BeanShell的jar文件拖到JAVA_HOME的ext目錄也可以直接加到classpath中。
- windows用戶請將bsh.jar放在JAVA_HOME/jre/lib/ext文件夾,OSX用戶可以放在/Library/Java/Extensions.
或者增加BeanShell到你的classpath目錄,如:
unix: export CLASSPATH=$CLASSPATH:bsh-xx.jar
windows:set classpath %classpath%;bsh-xx.jar
然后你就可以運行BeanShell在GUI或命令行模式:
- java bsh.Console // run the graphical desktop
or
java bsh.Interpreter // run as text-only on the command line
or
java bsh.Interpreter filename [ args ] // run script file
可以在你的應用程序內部來運行,也可以作為debug及servlet的遠程服務器模式,或一個Applet內部來運行BeanShell。請參考"BeanShell Modes of Operation"獲得更多詳情。
BeanShell GUI
用GUI模式啟動BeanShell后,將打開一個桌面視窗。用鼠標右擊在桌面的背景上,你可以打開另一個控制臺視窗及其它的工具如一個簡單的類游覽器。
每一個控制臺視窗運行一個獨立的BeanShell解釋器。這個圖形化的控制臺支持基本的歷史命令,行編輯,剪切和粘貼,甚至類和變量名的自動完成功能。從控制臺你能開啟一個簡單的編輯視窗。在它里面,你可以編寫腳本和使用‘eval’選項求表達式的值。
Java語句和表達式
BeanShell能理解標準的JAVA語句,表達式,和方法宣告。語句和表達式的內容可以是:變量,宣告,賦值,方法調用,循環,條件等。
在
Java程序中你必須嚴格的使用它們,但在BeanShell中,你可以用“寬松類型”(loosely
typed)的方式來使用它們。也就是說,你可以在寫腳本時偷懶,不進行變量類型的宣告(在原始數據類型和對象都可以)。如果你試著用錯變量類
型,BeanShell將會給出一個錯誤。
這里有一些例子:
- foo = "Foo";
four = (2 + 2)*2/2;
print( foo + " = " + four ); // print() is a BeanShell command
// Do a loop
for (i=0; i<5; i++)
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);
有用的BeanShell命令
在
剛才那個例子中我們用了一個內建在BeanShell中的一個方便的命令print(),來顯示變量的值。print()跟ava的
System.out.println()非常的相像,除非它能保證輸出總是命令行。print()也可以顯示一些對象的類型(如數組),但比Java的
更詳細。另一個相關的命令是show(),用來開啟與關閉顯示你輸入的每一行的結果。
這兒是一些其它的BeanShell的命令:
source(), run() - 將一個bsh腳本讀到解釋器或運行在另一個解釋器。
frame() - 顯示一個Frame或JFrame的GUI組件.
load(), save() - 載入和保存一個序列化的對象到一個文件.
cd(), cat(), dir(), pwd(), etc. - 類unix的shell命令。
exec() - 運行一個本地的程序。
javap() - 打印一個對象的方法和字段,類似于Java的javap命令。
setAccessibility() - 開啟無限制的存取private 和protected的組件。
要獲得更多的信息請查看BeanShell命令的詳細清單。
提示:
BeanShell命令并不是真的"內建"其中的,而是作為腳本方法自動從classpath載入的. 你可以擴展基本命令集并加到classpath中作為自訂義的腳本來使用。
腳本方法
你可以在bsh中宣告和使用方法,就像在java的類中一樣。
- int addTwoNumbers( int a, int b ) {
return a + b;
}
sum = addTwoNumbers( 5, 7 ); // 12
bsh的方法可以有動態的(寬松的)參數和返回類型。
- add( a, b ) {
return a + b;
}
foo = add(1, 2); // 3
foo = add("Oh", " baby"); // "Oh baby"
實現Interface
注意:如果要BeanShell能實現任意的Interface,必須有jdk1.3及以上支持。
你可以在腳本中用標準的Java內部類的語法來實現Interface.例如:
- ActionListener scriptedListener = new ActionListener() {
actionPerformed( event ) { ... }
}
你
可以不用實現Interface的所有方法,而只用實現你需要的方法。如果代碼中調用了未被實現的方法,將丟出異常。如果你想重載大量的方法的行為--例
如為日志生成一個"啞"適配器--你可以在腳本對象中實現一個特殊的方法:invoke(name,args)。invoke()方法用來處理任何未被定
義的方法的調用:
- ml = new MouseListener() {
mousePressed( event ) { ... }
// handle the rest
invoke( name, args ) { print("Method: "+name+" invoked!");
}
腳本對象
在
BeanShell中,和在JavaScript與Perl中一樣,腳本對象是用封閉的方法體一構成的。通過在方法未尾返回一個特殊值"this",你就
可以像使用方法一樣調用這個對象了。在這個方法調用時,你可以給與它任何的值。通常對象內部需要包括方法,所以BeanShell的腳本方法在一定程度上
可再包含一些方法以構成腳本對象。例如:
- foo() {
print("foo");
x=5;
bar() {
print("bar");
}
return this;
}
myfoo = foo(); // prints "foo"
print( myfoo.x ); // prints "5"
myfoo.bar(); // prints "bar"
如果這些代碼對你來說很陌生,別急,請用戶手冊可得到更透徹的解釋。
在
你的腳本中,BeanShell腳本對象(也就是先前例子中的"this"參照)能自動實現任何JAVA介面類型。當JAVA代碼調用相應與之通訊的腳本
方法內的方法。當你試著將腳本對象作為參數傳給Java方法時,BeanShell會自動將它造型(cast)為相應的類型。如要傳遞BeanShell
外部的對象時,你可以在需要時顯式的進行造型(cast).請看用戶手冊中的詳細內容。
從你的應用程序調用BeanShell
通過建立一個BeanShell解釋器,使用eval()或source()命令,你可以在你的應用程序中求文本表達式的值和運行腳本。如果你希望在你的腳本內部使用一個對象,可以用set()方法傳遞對象的變量參照給BeanShell,并通過get()方法取得結果。
- import bsh.Interpreter;
Interpreter i = new Interpreter(); // Construct an interpreter
i.set("foo", 5); // Set variables
i.set("date", new Date() );
Date date = (Date)i.get("date"); // retrieve a variable
// Eval a statement and get the result
i.eval("bar = foo*10");
System.out.println( i.get("bar") );
// Source an external script file
i.source("somefile.bsh");
BeanShell將成為Java平臺上的第三種編程語言
|
2005-06-08 點擊:8 來源:CSDN 作者:CSDN |
JCP接納了一個新的技術規范進入標準化進程,這個編號為JSR-274的技術規范將把BeanShell引入為Java平臺上支持的又一種編程語言。
JSR-
274(http://jcp.org/en/jsr/detail?id=274)是由 Patrick
Niemeyer提交的技術規范,其目標是將BeanShell腳本語言(http://www.beanshell.org/)規范化為Java虛擬機
平臺上支持的第三種編程語言。除了Java之外,Java虛擬機還支持Groovy腳本語言。Doug
Lea、Apache和Google三個JCP執委會成員對此規范表示了支持。
按照Java最初的設計思路,有很多語言都可以在JVM上
運行(詳細列表參見http://en.wikipedia.org/wiki/List_of_Java_scripting_languages),
但這些語言大多沒有流行起來。直到2004年為止,Java平臺事實上只有一種編程語言,也就是Java。2004年3月,Groovy(JSR-
241)成為了Java平臺上的第二種編程語言。
消息全文請看:http://rmh.blogs.com/weblog/2005/05/beanshell_the_3.html
|
http://www.cn-java.com/target/news.php?news_id=2450
簡介:
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; i++)
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; i++)
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語法
/*
Standard Java syntax
*/
// 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; i++)
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語法
/*
Loosely Typed Java syntax
*/
// 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; i++)
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 variable
j=42;
}
print( i ); // Error! 'i' is undefined.
print( j ); // 42
for( z=0; z<10; z++ ) { } // untyped for-init variable
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 <<=
@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++ ) {
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();
更多的文檔參考BeanShell網站
http://www.beanshell.org
posted on 2008-10-08 14:34
xiaoxinchen 閱讀(2471)
評論(0) 編輯 收藏