The integration of CLOS is mainly the fact that the functions that take a jobject also accept a CLOS instances of the class standard-java-object, which has a slot containing the jobject to use. That includes arguments to Java callers, Java arrays in the array interface, and return values from Lisp to Java. However, values that come from Java to Lisp (return values of caller, arguments in Java to Lisp calls), are always a jobject or primitives.
You can create a subclass of standard-java-object either by the usual way of including it (or a subclass of it) in the superclasses of your class, or by using the keywords arguments to importing functions and macro. To be able to construct a jobject for a class without the constructor, the class-name must be passed to define-java-constructor. This is done automatically by the importing functions.
When defining the class using the importing function, you can force it to create the complete hierarchy of superclasses to match all Java superclasses and implemented interfaces. This creates overhead and is not necessarily useful, but in some circumstances it may be what you need. You can also force the hierarchy explicitly by using ensure-lisp-classes-from-tree.
The jobject in an instance of standard-java-object can be read and written by the accessor java-instance-jobject
. Alternatively you can call create-instance-jobject or create-instance-jobject-list to create the jobject for a given instance.
A simple interface for making an instance and its jobject together is make-java-instance, but this does not provide a way to pass arguments to make-instance. The initarg :construct
to make-instance on a subclass of standard-java-object can be used to make the instance and the jobject. Note, however, that the jobject is created in the cl:initialize-instance
method of standard-java-object, which may or may not be called before your cl:initialize-instance
methods (depending on the order of the superclasses). To ensure that the jobject is created after the CLOS instance initialization is complete, do not pass the :construct
initarg, and instead call create-instance-jobject or create-instance-jobject-list afterwards.
The argument to create-instance-jobject-list and to the :construct
initarg is either a list of arguments to the constructor, or t
, which means use the default arguments list. The default arguments list is created by calling default-constructor-arguments on the instance. The default method returns nil
, which is good enough for some Java classes, but not all. Note that if you pass :construct
to make-instance, default-constructor-arguments will be called on the instance before all the cl:initialize-instance
methods have been called, which may be a problem if it depends on some values that may be put in by other cl:initialize-instance
methods. To avoid this issue use create-instance-jobject-list with t
on the result of make-instance.
If you have a jobject, and there is a CLOS class defined for its Java class, you can create a CLOS instance for it using create-instance-from-jobject. create-instance-from-jobject finds the class using the record that is created by record-java-class-lisp-symbol. The call to record-java-class-lisp-symbol is done automatically by the importing interface, but you can also call it directly.
LispWorks User Guide and Reference Manual - 13 Feb 2015