Skip to main content

Java Basics from BBj

BBj's Java interop starts with the use statement for imports and the new keyword for object creation. If you have used Java, the syntax will feel familiar -- with a few BBj-specific differences around type handling and error reporting.

Importing Java Classes

There are two ways to reference Java classes in BBj.

With use (recommended):

use java.util.HashMap
use java.util.ArrayList

map! = new HashMap()
list! = new ArrayList()

The use statement imports the class so you can reference it by short name throughout the program. Place use statements at the top of your file, before any executable code.

Fully qualified (inline):

map! = new java.util.HashMap()

This works without a use statement but becomes verbose when the same class appears multiple times.

Creating Objects and Calling Methods

Java's HashMap is one of the most commonly used Java classes in BBj code. It provides key-value storage with fast lookups:

use java.util.HashMap
use java.util.Iterator

map! = new HashMap()
map!.put("name", "Alice")
map!.put("role", "Developer")
map!.put("team", "Platform")

rem Retrieve a value by key
print "Name: ", map!.get("name")
print "Size: ", map!.size()

rem Iterate over all entries
iter! = map!.keySet().iterator()
while iter!.hasNext()
key! = iter!.next()
print key!, " = ", map!.get(key!)
wend

The pattern is: create the map, populate it with put(), retrieve with get(), and iterate using keySet().iterator(). This is standard Java collection usage -- the same API you would use in Java itself.

ArrayList -- a resizable list:

use java.util.ArrayList

list! = new ArrayList()
list!.add("first")
list!.add("second")
list!.add("third")

rem Access by index
print "First item: ", list!.get(0)
print "Size: ", list!.size()

rem Iterate with a for loop
for i = 0 to list!.size() - 1
print list!.get(i)
next i

Other Common Java Classes

File -- file path manipulation and existence checks:

use java.io.File

f! = new File("/path/to/file.txt")
if f!.exists() then print "File exists, size: ", str(f!.length()), " bytes"

SimpleDateFormat -- date formatting:

use java.text.SimpleDateFormat
use java.util.Date

fmt! = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
print "Current time: ", fmt!.format(new Date())

Date -- working with dates:

use java.util.Date

now! = new Date()
print "Milliseconds since epoch: ", str(now!.getTime())

Any class available on the JVM classpath is accessible from BBj using these patterns.

Type Mapping Between BBj and Java

BBj handles type conversion automatically across the BBj-Java boundary for most common types:

BBj TypeJava TypeNotes
BBj string ($ suffix)java.lang.StringAutomatic conversion both ways
BBj number (no suffix)Java numeric types (int, double, etc.)Automatic for most cases
null()nullBBj's null literal maps to Java null
Object reference (! suffix)Java objectBBj object variables hold Java objects directly

When automatic conversion is not sufficient, use the cast() function for explicit type casting:

use java.net.HttpURLConnection
use java.net.URL

url! = new URL("https://example.com")
conn! = cast(HttpURLConnection, url!.openConnection())

The cast() function tells BBj to treat the return value as a specific type. This is necessary when a Java method returns a supertype (like URLConnection) but you need to call methods defined on a subtype (like HttpURLConnection).

The ! Suffix Convention

BBj variables that hold object references use the ! suffix. This is not optional for Java objects -- it is enforced by the interpreter:

use java.util.HashMap

map! = new HashMap() : rem correct -- object reference
rem map = new HashMap() : rem WRONG -- would cause an error

The ! suffix tells BBj that this variable holds an object reference (either a BBj custom object or a Java object). Variables without ! hold primitive values (strings with $, numbers with no suffix).

For more on BBj's class syntax, constructors, and methods, see the Object-Oriented Programming chapter.

Reading Legacy Code

See Reading Legacy Code for legacy Java interop patterns including pre-use fully-qualified names, ADDR()/CALL callbacks, and procedural Java usage.

Further Reading