DynamicJava is a JavaTM interpreter which try to follow the Java Language Specification. Some extensions have been added to ease the creation of small programs. All these extensions have been added with the same goal in mind: reduce the amount of code to write and make it easy to translate a script to a valid Java program. The following sections describe these extensions.Top-level
A Java program (called a compilation unit in the specification) can contain:A DynamicJava script is a Java program. It can also contain statements, expressions and function declarations. The meaning of a
- An optional
package
clause,- Optionals
import
clauses,- One or more
class
orinterface
declarations.package
clause is different. Here is an example (top_level.djava):System.out.println("Example script"); // Place the script in the package p. package p; public class C { public C() { System.out.println("C created"); } } // Place the script in the anonymous package. package; import p.*; // Create an instance of p.C new C();The
package
andimport
clauses can be placed anywhere at the top-level in a script. Thepackage
clause used without package name places the script in the anonymous package (the package where the application was launched).Variables
In scripts declaring variables is optional. The interpreter automatically declares a variable when an unknown identifier is encountered on the left side of an assignment. A variable declared by the interpreter has no difference with an explicitly declared one: the interpreter assigns a type to the variable (the type of the right hand side of the assignment) and this type will be enforced later in the program. This means that it is not possible to dynamically modify the type of a variable.
Note: The variable declared in an expression likevar = null;
is ajava.lang.Object
.Functions
The syntax used to declare a method can be used to declare a function in the top level environment. The resulting function can be used everywhere in the top-level environment and in the body of every functions. Functions are not visible from classes, can be recursive and can be overloaded, exactly like JavaTM methods.
Here is an example that use functions (functions.djava):import java.math.*; // A first version of the factorial function that // takes an int as parameter BigInteger fact(int n) { // A forward reference to fact(BigInteger n) return fact(new BigInteger("" + n)); } // An overloaded recursive version of the factorial // function that takes a BigInteger as parameter BigInteger fact(BigInteger n) { return (n.equals(BigInteger.ZERO)) ? BigInteger.ONE : n.multiply(fact(n.subtract(BigInteger.ONE))); } System.out.println("fact(30) = " + fact(30));The body of a function can contain forward references to classes and to other functions. In fact the body of a function is lazily interpreted and the type checking is made the first time the function is called. So every class and function declared before the first invocation of a function can be used in its body.
As mentioned above, the function declaration syntax is exactly the same as the method declaration syntax. This means that modifiers (
public
,final
,synchronized
, ...) andthrows
clause can be used. It is allowed to ease the transition from functions to methods but it is ignored by the interpreter.Classes
The class declaration has exactly the same semantic in JavaTM and in DynamicJava programs with one exception: the top-level anonymous classes. The choice has been made to export the final variables declared in the top-level environment to these classes.
Casts
Some runtime casts are optional. The following example is a script that contains casts (casts1.djava):
i = 1; byte b1 = (byte)(i + 1); Object o = new Byte(b1); Byte b2 = (Byte)o; Number n = (Number)o; b1 = ((Byte)o).byteValue();The next example is the same script without the optional runtime casts (casts2.djava):
i = 1; byte b1 = (byte)(i + 1); Object o = new Byte(b1); Byte b2 = o; Number n = o; b1 = ((Byte)o).byteValue();The cast at the last line cannot be removed because the interpreter needs the information it holds to find the
byteValue
method while it makes the type checking of the expression.