Calling Java From BBj

Description

To allow for integration with Java, BBj keeps all user-defined identifiers as entered; they are not converted to uppercase. Variables, such as X!, are treated as being case-insensitive, so that X! and x! refer to the same variable. The following rules are used when passing BBj values to Java:

BBj Type

Java Type

Example

String Expression

A BBj String expression can be passed to a parameter that accepts a java.lang.String or a java.lang.Object.

A=Integer.parseInt(A$)

Integer number

An integer numeric expression can be passed to a parameter that accepts a Java int, long, float, double, or boolean. For boolean, zero is passed as false and non-zero is passed as true.

I!=new Integer(123)

Real number

A non-integer (real) numeric expression can be passed to a parameter that accepts a Java double or boolean. When matching boolean, the non-zero value is passed as true.

D!=new Double(12.95)

Java primitive values

Java primitive types are returned to BBj from Java calls, and include boolean, byte, short, char, int, long, float, and double. A Java primitive value can be passed in a subsequent Java call to any parameter that accepts that primitive type or any primitive type to which it can be promoted, based on Java promotion rules.

PI!=Math.PI

L!=new Long(PI!)

 

Object

Any other type of object will simply match itself, or a superclass of itself.

TZ!=java.util.TimeZone.getDefault()

D!=new java.util.Date()

DST=TZ!.inDaylightTime(D!)

 

The following rules are used when passing values back from Java to BBj:

 

Java Type

BBj Type

Example

String

String

DATE!=new java.util.Date()

DATE$=DATE!.toString()

BBjNumber (returned from some BBjAPI functions)

BBjNumber

CONTEXT=BBjAPI().getSysGui().getContext()

boolean

BBj treats boolean values as being interchangeable with numbers. A Java boolean is returned to BBj as the number true (1) or false (0). If the number is stored in an object variable, it is tagged as being a boolean type.

X!="string"

Y!="string"

EQUAL!=X!.equals(Y!)

byte

This example returns a numeric value of 123, tagged as a Java byte.

byte!=Byte.parseByte("123")

char

This example returns a numeric value corresponding to the decimal separator character in the system default Locale. The number is tagged as being a Java char.

dfs!=new java.text.DecimalFormatSymbols()

sep!=dfs!.getDecimalSeparator()

short

This example returns a numeric value of 123, tagged as a Java short.

short!=Short.parseShort("123")

int

This example returns a numeric value of 6, tagged as a Java int.

X!="string"

L!=X!.length()

long

This example returns the current time as the number of milliseconds that have elapsed since midnight, January 1st, 1970, UTC. The number is tagged as a Java long.

now!=System.currentTimeMillis()

float

This example returns the number 12.95, tagged as a Java float.

float!=Float.parseFloat("12.95")

double

This example returns the number PI, tagged as a Java double.

PI!=Math.PI

void

Void functions return null(). In the case of a void function, the return value is not meaningful.

B!=new StringBuffer()

X!=B!.ensureCapacity(100)

B!.ensureCapacity(100); REM ' preferred

Object (other than String or BBjNumber)

Anything else is returned as an object. Attempting to assign an object to a numeric or string variable will generate a runtime error.

Locale!=new java.util.Locale("de","DE")

In most cases, the mapping from BBj to Java and back is intuitive, but Boolean (true/false) data is potentially confusing due because of differing concepts in the two languages. BBj can perform logical tests on any numeric value, treating zero as false and all other values as true. Java, on the other hand, has a boolean data type, distinct from numeric types. When a BBj program invokes a Java method, BBj can pass any numeric or logical expression to a Boolean parameter; BBj passes on the value of 'false' to Java if the number is 0, and 'true' for any non-zero value. Likewise, when a Java method returns a Boolean value, BBj gets back a value of false (0) or true (1). Unlike Java, BBj does not reserve the words true or false as keywords, so a test of if someValue = true then … will fail unless the program defines true as a numeric variable with a non-zero value.

BBjAPI methods specify a boolean data type for many parameters and return values.The BBj programmer is free to treat these data types as equivalent to numbers.

For overloaded methods (multiple Java methods with the same name that accept different data types), knowing which version is selected can be unclear. The SETTRACE output shows the mapping of data values from BBj to Java, and the return type of data passed back from Java.

Example 1

0001 SETTRACE
0010 REM ' Is Daylight Savings Time active?
0020 let TZ!=java.util.TimeZone.getDefault()
0030 let DATE!=new java.util.Date(java.lang.System.currentTimeMillis())
0040 let DST=TZ!.inDaylightTime(DATE!)
0050 PRINT date!,": ",; IF DST then PRINT "Daylight time" else PRINT
0050:"Standard time"
>RUN
0010 REM ' Is Daylight Savings Time active?
0020 let TZ!=java.util.TimeZone.getDefault()
>JAVA: java.util.TimeZone.getDefault() returns java.util.TimeZone

(The returned object is of type java.util.TimeZone)

0030 LET DATE!=new java.util.Date(java.lang.System.currentTimeMillis())
>JAVA: java.lang.System.currentTimeMillis() returns long
>JAVA: new java.util.Date((long)1008116501301)

(currentTimeMillis() returns a long value, and the final returned object is of type java.util.Date)

0040 LET DST=TZ!.inDaylightTime(DATE!)
>JAVA: java.util.SimpleTimeZone.inDaylightTime((java.util.Date)
Tue Dec 11 16:21:41 PST 2001) returns boolean

(The return value, assigned to DST, is a boolean. It will be the number 1 or 0 in BBj)

0050 PRINT date!,": ",; IF DST THEN PRINT "Daylight time" ELSE PRINT "Standard time"
Tue Dec 11 16:21:41 PST 2001: Standard time
***** END

Example 2 (varargs)

Java varargs methods are defined to accept an arbitrary number of parameters of a given type at the end of the argument list. In the past, it was tricky to call these methods from BBj. In BBj 17.10 and higher, BBj can directly call varargs methods without the need for special workarounds. This example is a direct translation of Oracle's Java varargs sample.

use java.text.MessageFormat
use java.util.Date
declare Object[] arguments!
arguments! = new Object[3]
arguments![0] = new Integer(7)
arguments![1] = new Date()
arguments![2] = "a disturbance in the Force"
result$ = MessageFormat.format("At {1,time} on {1,date}, there was {2} on planet " + "{0,number,integer}.", arguments!)
print result$
result$ = MessageFormat.format("At {1,time} on {1,date}, there was {2} on planet " + "{0,number,integer}.", new Integer(3), new Date(), "a disturbance in the Force")
print result$