Module Java

module Java: sig .. end
Manipulation of Java references.

The ocamljava compiler allows to manipulate Java references through two types, namely cn java_instance and cn java_extends. The former is used to designate instances of exactly one classes, while the latter is used to designate instances of either one classes or any of its subclasses. In both cases, the type parameter is used to specify the class. It uses the fully-qualified name of the classe, just replacing dots with single quotes. The type of Java strings is thus written java'lang'String java_instance.

This module contains the functions needed to create new instances, call methods, and access fields. Such functions use descriptors to determine the constructor/method/field to use. These descriptors are written as string litterals; for example, parsing a string into an integer can be done by writing:

      let integer = call "java.lang.Integer.parseInt(java.lang.String):int" s
    

However, it is possible to use simple names rather than qualified names for classes if their packages have been opened. Initially, the java.lang package is the only one opened. A package can be opened though a modified open Package'packname directive; for example opening the javax.awt package can be done by writing:

      open Package'java'awt
    
It is also possible to take advantage of opened packages in types, by replacing the package name with an underscore. The type of Java strings can thus be written _'String java_instance.

Moreover, types of fields and return types of methods can be elided as long as there is no ambiguity. Types of method/constructor parameters can also be replaced with single underscores, leading to the lighter code to parse an integer:

      let integer = call "Integer.parseInt(_)" s
    
The compiler will issue an error if there is an ambiguity.

Finally, an exception is defined to wrap Java exceptions on the OCaml side:

      exception Java_exception of java'lang'Throwable java_instance
    

Warning: to be able to use the functions from this module, java extensions should be enabled by passing the -java-extensions option to the ocamljava compiler.



Instance creation

val make : 'a java_constructor -> 'a
make "constructordesc" p0 ... pn calls constructor constructordesc with parameters pi and returns the created instance. For example, the following code creates an object instance:
      let inst = make "java.lang.Object()" ()
    

Raises Java_exception if the constructor throws an exception.

val make_array : 'a java_array_shape -> 'a
make_array "arraydesc" dim1 ... dimn builds and returns an array with n dimensions. Each element is initialized to the default value (that is zero for primitive types, and null for reference types). For example, the following code creates a 2x3 matrix of byte values:
      let arr = make_array "byte[][]" 2l 3l
    

Raises Java_exception if a dimension is negative.

val make_array_dims : 'a java_array_shape_dims -> 'a
make_array_dims "arraydesc" dim1 ... dimn is similar to make_array, except that the array descriptor is made of two kinds of dimension specifiers: For example, the following code creates a two-dimensional array, but only the first dimension of the array is allocated and initialized:
      let arr = make_array "byte[_][]" 2l
    

Raises Java_exception if a dimension is negative.


Method call

val call : 'a java_method -> 'a
call "methoddesc" p0 ... pn calls and returns the result of method methoddesc called with parameters pi, where p0 is the instance to call method upon if the method is not static. For example, the following code compares strings s1 and s2:
      let cmp = call "java.lang.String.compareTo(java.lang.String):int" s1 s2
    

Raises Java_exception if the method throws an exception.


Field access

val get : 'a java_field_get -> 'a
get "fielddesc" obj retrieves the value of field fielddesc for instance obj. The obj value should not be replaced by () if fielddesc designates a static field. For example, the following code gets the maximum value of a integer:
      let max_int = get "java.lang.Integer.MAX_VALUE:int" ()
    

val set : 'a java_field_set -> 'a
set "fielddesc" obj x changes the value of field fielddesc for instance obj to x. The obj value should not be provided if fielddesc designates a static field. For example, the following code sets the height of a dimension to zero:
      let () = set "java.awt.Dimension.height:int" dim 0l
    


Null value

val null : 'a java_instance
The null value.
val is_null : 'a java_instance -> bool
is_null x returns true iff x is equal to null.
val is_not_null : 'a java_instance -> bool
is_not_null x returns false iff x is equal to null.

Equality test

val equal : 'a java_instance -> 'b java_instance -> bool
equal x y returns true if x and y designate the very same reference.
val not_equal : 'a java_instance -> 'b java_instance -> bool
not_equal x y returns false if x and y designate the very same reference.

Class test

val instanceof : 'a java_type -> 'b java_instance -> bool
instanceof "classname" x returns true if x is an instance of classname or one of its subclasses, where classname can designate an array type.
val cast : 'a java_type -> 'b java_instance -> 'a
cast "classname" x casts x to an instance of classname, where classname can designate an array type.

Raises Java_exception if the cast fails.


Exception throw

val throw : java'lang'Throwable java_extends -> 'a
throw x raises the exception instance x (wrapped into a Java_exception on the OCaml side).

Synchronization

val synchronized : 'a java_instance -> (unit -> unit) -> unit
synchronized obj (fun () -> ...) is equivalent to the Java code synchronized (obj) { ... }.

Raises Java_exception if the obj is null.


Interface implementation

val proxy : 'a java_proxy -> 'a
proxy "interfacenames" impl returns an instance that implements interfacenames (a comma-separated list of interface names) using the methods provided by impl. For example, an instance of java.lang.Runnable can be built using the following code:
      proxy "java.lang.Runnable" (object
        method run = ...
      end)
    

When only one interface is provided, the instance returned by proxy has this type, otherwise it has type java.lang.Object.

Besides interface names, it is also possible to use java.lang.Object in order to be able to override the methods from the java.lang.Object class. However, those methods are different as they take an additional leading parameter that is the proxy instance.

class default_implementations : object .. end
This class provide the default implementations for the methods of java.lang.Object.

Miscellaneous

val wrap : 'a java_instance -> 'a java_instance option
wrap x wraps the reference x into an option type: