![]() Home | ![]() Back | ![]() Contents | ![]() Next |
Here are some examples:
/*
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);
|
You can also define your own methods and use them just as you would inside a Java class. We'll get to that in a moment.
/*
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);
|
This may not seem like it has saved us a great deal of work. But you will see the difference when you come to rely on scripting as part of your development and testing process; especially for in interactive use.
When a "loose" variable is used you are free to reassign it to another type of Java object later. Untyped BeanShell variables can also freely hold Java primitive values like int and boolean. Don't worry, BeanShell always knows the real types and only lets you use the values where appropriate. For primitive types this includes doing the correct numeric promotion that the real Java language would do when you use them in an expression.
try {
int i = 1/0;
} catch ( ArithmeticException e ) {
print( e );
}
|
But you can loosely type your catch blocks if you wish:
try {
...
} catch ( e ) {
print( "caught exception: "+e );
}
|
| Note: As of BeanShell version 1.3 the default scoping of loosely typed variables was changed to be more consistent with Java. BeanShell still supports an alternate scoping used in earlier versions. This mode can be enabled for legacy code by setting the system property "localscoping" to true. See appendix "Local Scoping". |
Variable scoping in BeanShell behaves, wherever possible, just like that in Java. Ordinary Java, however, does not offer "loose" variables (variables that can be used without being declared first). So we must define their behavior within BeanShell. We'll see in the next section that untyped variables - variables that are not declared and not assigned a value elsewhere - default to the local scope. This means that, in general, if you assign a value to a variable without first declaring it, you are creating a new local variable in the current scope.
Untyped variables in BeanShell, however, are not constrained by blocks. Instead they act as if they were declared at the outer (enclosing) scope's level. With this in mind, BeanShell code looks just like Java code. In BeanShell if you declare a typed variable within a block it is local to the block. But if you use an untyped variable (which looks just like an ordinary assignment in Java) it behaves as an assignment to the enclosing scope.
This will make sense with a few examples:
// 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.
|
Variables declared in the for-init area of a for-loop follow the same rules as part of the block:
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
|
Modifiers may not be applied to untyped variables.
button = new java.awt.Button();
button.label = "my button"; // Equivalent to: b.setLabel("my button");
print( button.label ); // Equivalent to print( b.getLabel() );
|
JavaBean properties are simply pairs of "setter" and "getter" methods that adhere to a naming convention. In the above example BeanShell located a "setter" method with the name "setLabel()" and used it to assign the string value. It then found the method named getLabel() to retrieve the value.
Boolean properties may optionally use the syntax "is" for their "getter". e.g.
Float f = new Float(42f); print( f.infinite ); // Equivalent to print( f.isInfinite() ); // false |
If there is any ambiguity with an actual Java field name of the object (e.g. label in the above example) then the actual field name takes precedence. If you wish to avoid any ambiguity BeanShell provides an additional, uniform syntax for accessing both Java Bean properties and Hashtable or Map entries. You may use the "{}" curly brace construct with a String identifier as a qualifier on any variable of the appropriate type:
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");
|
Where the java.util.Collections API is available, Maps are also supported.
List foo = getSomeList();
for ( untypedElement : foo )
print( untypedElement );
for ( Object typedElement: foo )
print( typedElement );
int [] array = new int [] { 1, 2, 3 };
for( i : array )
print(i);
for( char c : "a string" )
print( c );
|
Supported iterable types include all the obvious things.
dateobj = new Date();
switch( dateobj )
{
case newYears:
break;
case christmas:
break;
default:
}
|
BeanShell supports boxing and unboxing of primitive types. For example:
int i=5; Integer iw = new Integer(5); print( i * iw ); // 25 Vector v = new Vector(); v.put(1); int x = v.getFirstElement(); |
// Standard Java import javax.xml.parsers.*; import mypackage.MyClass; |
In BeanShell import statements may appear anywhere, even inside a method, not just at the top of a file. In the event of a conflict, later imports take precedence over earlier ones.
A somewhat experimental feature is the "super import". With it you may automatically import the entire classpath, like so:
import *; |
The first time you do this BeanShell will map out your entire classpath; so this is primarily intended for interactive use. Note that importing every class in your classpath can be time consuming. It can also result in a lot of ambiguities. Currently BeanShell will report an error when resolving an an ambiguous import from mapping the entire classpath. You may disambiguate it by importing the class you intend.
| Tip: The BeanShell which() command will use the classpath mapping capability to tell you where exactly in your classpath a specified class is located: bsh % which( java.lang.String ); Jar: file:/usr/java/j2sdk1.4.0/jre/lib/rt.jar |
See "Class Path Management" for information about modifying the BeanShell classpath at run-time with the addClassPath() or setClassPath() commands.
Also see "BeanShell Commands" for information about importing new BeanShell commands from the classpath.
Two BeanShell package classes are also imported by default:
Finally, we should mention that BeanShell commands may be imported from the classpath. The default commands are imported in the following way:
importCommands("/bsh/commands");
|
We will discuss how to import your own commands in a later section.
| Tip: The classes java.awt.List and java.util.List are both imported by default. Because java.util.List is imported later, as part of the java.util package, it takes precedence. To access java.awt.List simply import it in, or the java.awt package again your script. Later imports take precedence. |
| @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 | >>>= |
![]() Home | ![]() Back | ![]() Contents | ![]() Next |