How to use Java Objects in DataBasic
Introduction
Java DataBasic objects (DBOs) are opaque variables that reference external Java language objects. They can be copied, compared and deleted like any other variable but cannot be directly used in arithmetic or string operations.
Java objects are a subset of generic DataBasic objects. The objects are used in DataBasic as you would if writing Java code to run in a true Java environment, the main exception being that the "." (dot) operator is replaced with the DataBasic "->" (hyphen greater-than) operator.
The objects and their associated statements are created and processed by a Java Language Server under the control of the DataBasic run time.
To support object orientated language syntax (for example, new), a set of special methods is available. Special methods always have a % character prefix (for example, %New) to identify them from standard methods. Special method keywords are case-insensitive.
Java is a heavily typed language, in contrast to DataBasic where variables are largely untyped. Because of this it is possible for the data type of method arguments to be ambiguous. A new 'cast' syntax has been introduced to DataBasic to alleviate this problem. A variable can be explicitly cast to a type by using a cast operator. For example, "(int16)Var
forces Var
to take the type of a 16-bit integer for the purposes of a method call.
Note
Examples of using Java objects to create a PDF and an Excel spreadsheet using data in the HOTEL account are available in /SYSPROG/BP as ROOMS.PDF and ROOMS.XLSX respectively. These examples require third-party Java packages to be installed before they can be used. See the comments in the examples.
Connecting to a Java Language Server
Before any Java objects can be used or created at least one connection must be made to a Java Language Server (JLS) by using the %Connect special method, for example:
JavaLS = %Connect(JAVA)
This form of the method creates a connection object that references the JLS on the local host. The first connection made automatically becomes the default connection, and does not have to be explicitly named thereafter. If necessary, connection objects that reference other JLSs can be established but unlike the default connection they must be explicitly named whenever they are used.
Importing Java packages
A package in Java is a mechanism to encapsulate sub-packages, classes, and interfaces. Once a connection object has been created it should be associated with any required packages by using the %Import special method. Java packages are usually stored in libraries that are held in a .jar file on the system running the JLS.
For example:
%Import(java.io)
The %Import special method behaves much like the Java import statement.
Creating objects
Once there is a default connection object the %New special method can be used to create DBOs. An object is instantiated within the language server and this object is referenced by a DBO variable. The first parameter of %New is the class name, and if the class has a default constructor or a parameterless "no-arg" constructor, that is all you need. If the class has a parameterised constructor the class name can be followed by a comma-separated list of the initial values required by the constructor (or one of the constructors, if it is overloaded).
For example:
UserAccount = %New(UserProfile, "Smith", "Paul", "paul.smith@Mail4U.eu")
Here the DBO variable UserAccount references a UserProfile object that is an instantiation of the UserProfile class. The class's parameterised constructor is assumed to require surname, forename and email address strings. (The parameters do not have to be cast as strings because DataBasic can tell that they are strings.)
There is no limitation in DataBasic on the use of underlying objects. DBO variables are object references which can be passed around in the same way as normal variables and they can even be passed in and out of methods invoked on an object.
Public and private variables
Public variables in Java objects can be read and written directly but private variables must be accessed through their setter and getter methods, except on assignment when a parameterised constructor may be used.
Note
The DataBasic compiler knows nothing about constructor and method signatures. Any mistakes made with numbers of parameters or parameter types will only become apparent at run time.
Arrays
The variables contained in an array, also called the elements of the array, must all be of the same type. In addition to arrays of primitive data types, arrays of objects are also possible. Array indices start at 0. Multi-dimensional arrays are not supported.
Arrays of primitives
You can create an array of primitive data types by applying the %Array special method to a connection object and specifying the primitive data type and the initial element values — whether by a comma separated list or by a dynamic array.
The result is an array object which can referenced by a DBO variable in the usual way. For example:
FirstTenPrimes = %Array(Integer, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29)
Similarly, an array returned by a object method can be assigned to a DBO variable too:
MyCalculator = %New(MathCalculator) FirstTenPrimes = MyCalculator->GetPrimes(1, 10)
Conversely when %Array() is applied to an array object it returns an attribute mark delimited dynamic array (except for a Byte array, in which case it returns a string).
Arrays of objects
A DBO variable can refer to an array of objects. However, You cannot use %Array() to create an array of objects or convert such an array into a dynamic array.
Calling object methods
Java supports what is referred to as method signatures or overloading whereby there may be two or methods of the same name but with different parameter lists. The JLS can determine which method is being called from DataBasic by matching both the method name and the number and types of the parameters provided.
Static methods, properties and fields
These are methods, properties and fields that are not specific to any instantiated object of a given class but rather a persistent element of the class itself. In Java one would reference a static element by the class name rather than the name of a particular object.
The JLS supports a %Static special method by which DataBasic can access the static elements of a class. In the following example, MyCalculator refers to a new MathCalculater object, but AnyCalculator refers to (the static elements of) the MathCalculator class itself.
MyCalculator = %New(MathCalculator) AnyCalculator = %Static(MathCalculator)
Copying an object
DataBasic cannot duplicate an external Java language object. When a DBO variable is assigned to another DBO variable it is only the reference to the object that is copied, so that afterwards both variables reference the same object. A genuine copy is possible only if the class implements a method to do this.
Comparing two objects
Because DBO variables are only references to objects, the only meaningful comparison is equality or inequality: in other words, do these two DBO variables reference the same object, or not.
Deleting an object
Objects are automatically deleted when a DBO variable is reassigned or deleted (as in local subroutine or user function variables after the RETURN statement). In addition all objects saved in local variables are deleted when the program ends. Any DBOs saved in named common sections can be shared between program levels and are not lost when the program ends; this is not the case with data in unnamed common sections.
Object error handling
Object errors are treated as DataBasic exceptions and, once code is developed, it is recommended that an exception handler is always defined to catch any exceptions that may be thrown by the object. If no exception handler is defined, any errors generated by the DataBasic Object in run time will be treated as fatal and trapped by the DataBasic debugger.