Define a Java caller, which is a function that calls a Java method or a constructor.
lw-ji
define-java-caller name class-name method-name &key signatures static-p return-jobject non-virtual-p => result
define-java-constructor name class-name &key class-symbol signatures => result
name⇩ |
A symbol. |
class-name⇩ |
A string. |
method-name⇩ |
A string. |
signatures⇩ |
A list of strings. |
static-p⇩ | |
return-jobject⇩ | |
non-virtual-p⇩ | |
class-symbol⇩ |
A symbol. |
result |
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 a 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.
signatures is used for documentation only. If non-nil, it should be a list of strings, where each string is a signature of the Java method. LispWorks creates a documentation string from the list and sets the documentation of name, so that (documentation name 'function)
returns it. LispWorks does not parse the strings. signatures is used by the importing interface (see 15.2.1 Importing classes!) to document the definitions it produces.
static-p tells define-java-caller
whether it should look for static or non-static methods. If static-p is :either
, it tries both. If a call to name with some arguments matches both a static and a non-static method, an error of type java-program-error is signaled. If static-p is t
, define-java-caller
looks only for static methods, and if static-p is nil
, define-java-caller
looks only for non-static methods.
By default, when the method is an ordinary method (not static and not constructor), the invocation is virtual (normal Java behavior), which means that if the class of the first argument is a subclass of class-name, then it may invoke a method that is defined in a subclass of class-name. If non-virtual-p is non-nil, it makes the call non-virtual. Note that this is not normal Java behaviour, and may lead to surprising effects. non-virtual-p was added in LispWorks 8.0. When non-virtual-p is non-nil, it makes the caller look only for ordinary methods. If non-virtual-p is non-nil and static-p is t
, an error is invoked.
If the return value type is a primitive type, the caller converts the result of the method to the matching Lisp type before returning it. For method signature return types other than java.lang.String
and java.lang.Object
, the caller returns a jobject representing the Java object, or nil
if the method returned null. Constructors always return jobjects.
return-jobject controls the returned value when the method signature return value type is java.lang.String
or java.lang.Object
. With the default nil
, return value java.lang.String
is converted to a Lisp string, and return value java.lang.Object
is converted to Lisp value when possible (see 15.1 Types and conversion between Lisp and Java). If return-jobject is non-nil, all non-primitive values are returned as jobjects. For any other non-primitive return values in the method signature, a jobject is always returned. Note that name may call different methods with different return value types when called with different arguments.
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 (the caller) that calls a method in the class or a constructor of the class. Before performing the first call, the caller looks up and caches all the methods that are defined for class-name and are named method-name, including inherited methods. When it finds more then one method, the caller decides dynamically in each call which of these methods 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 15.1 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.
When the called method is an ordinary method (not static and not constructor), the invocation is virtual (normal Java behavior), which means that if the object's class is of a subclass of class-name, 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 LispWorks 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 caller 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 no method can be found).
The macros (when successful) return name.
define-java-caller
forms with the same class, consider using define-java-callers.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).
setup-java-caller
define-java-callers
write-java-class-definitions-to-file
import-java-class-definitions
verify-java-callers
verify-java-caller
jobject-call-method
call-java-method
call-java-static-method
call-java-non-virtual-method
15.2.2 Defining specific callers
LispWorks® User Guide and Reference Manual - 01 Dec 2021 19:30:46