All Manuals > LispWorks User Guide and Reference Manual > 41 The LW-JI Package





Define a Java caller, which is a function that calls a Java method or a constructor.




define-java-caller name class-name method-name &key signatures => result


define-java-constructor name class-name &key class-symbol signatures => result



A symbol.


A string.


A string.


A list of strings.


A symbol.



name or nil.


The macros define-java-caller and define-java-constructor define a Java caller, which is a function that calls a Java method or a constructor. Once this the caller is defined, calls to name ultimately invoke the Java method or constructor.

class-name must be the full name of a Java class, in the correct case. The '.' in the name may be replaced by '/'.

method-name must be a public method name of the class, with the correct case.

class-symbol, when it is non-nil, must name a class. It creates a mapping from the class to the constructor info, which allow functions like make-java-instance and create-instance-jobject to construct a jobject for an instance of the class named by class-symbol.

The effect of these macros is to set the symbol function of name to a function that calls the method in the class or the constructor of the class. When there is more than one method with the same name or more than one constructor (that is, it is overloaded), the function decides dynamically which of these to call, based on the arguments it gets.

For a successful call to name, it needs to be called with the correct arguments for the Java method. For an ordinary method, this must include the object on which the method should be applied, followed by the arguments of the method. For static methods and constructors, the arguments to name are just the arguments to the method/constructor.

For arguments of primitive type or a matching Java class (for example Integer), the Lisp argument must be either a Lisp object of matching type (see Types and conversion between Lisp and Java), or a jobject of the corresponding Java class. For strings (that is argument type java.lang.String) the argument must be a string, nil, or a jobject of type java.lang.String. For other non-primitive types, the argument must be a jobject of the correct class or nil. nil is passed as Java null for non-primitive types.

If the return value type is a primitive type or String, the function converts the result of the method to the matching Lisp type before returning it. For other return types, the function returns a jobject representing the Java object, or nil if the method returned null. Constructors always return jobjects.

When the method is an ordinary method (not static and not constructor), the invocation is virtual (normal Java behavior), which means that if the object is of a subclass of the class-name argument, it may invoke a method that is defined in a subclass of class-name.

Unlike the functions setup-java-caller and setup-java-constructor, the macros define-java-caller and define-java-constructor do not do any actual lookup, they just set up the symbol function and therefore they do not require running Java to perform the definition. They are also recognized by the Editor as definer forms, so source finders like the Editor command Find Source can locate them. These macros are intended as the main method of defining callers. They are produced by the importing interface to actually define the callers.

For callers defined by these macros, the actual lookup happens the first time the function is invoked, or for define-java-caller by verify-java-caller or verify-java-callers. If the lookup fails during the function call, an error is signaled of type java-class-error (when the class cannot be found) or java-method-error (when the method cannot be found).

The macros (when successful) return name.

  1. There is no difference in performance between functions defined by these macros and functions defined by setup-java-caller and setup-java-constructor. If you use setup-java-caller and setup-java-constructor in a delivered application then extra machinery is retained.
  2. If you need several define-java-caller forms with the same class, consider using define-java-callers.
  3. If you need many define-java-caller forms with the same class, you may want to use the importing interface. Even if you want to define your own names for the callers, you can either pass name-constructor to the import function, or use write-java-class-definitions-to-file and edit the definitions that it generated (which saves typing the method names).
  4. For methods it is possible to use verify-java-callers or verify-java-caller at run time to check that the methods are found, which is a way of guarding against typing errors in entering the method name.
  5. There is no restriction on defining more than one caller for the same method or constructor.
  6. Unlike setup-java-caller and setup-java-constructor, the name argument is not evaluated.
See also

Defining specific callers

LispWorks User Guide and Reference Manual - 20 Sep 2017