Changeset 13624

10/10/11 18:33:50 (10 years ago)

Subsection on intended class and a few minor tweaks.

1 edited


  • trunk/abcl/doc/manual/abcl.tex

    r13623 r13624  
    77\title{A Manual for Armed Bear Common Lisp}
    88\date{October 2, 2011}
    9 \author{Mark~Evenson, Erik~Huelsmann, Alessio~Stallo, Ville~Voutilainen}
     9\author{Mark~Evenson, Erik~Huelsmann, Alessio~Stalla, Ville~Voutilainen}
    9494  \item Missing statement of conformance in accompanying documentation
    95   \item The generic function sigatures of the DOCUMENTATION symbol do
     95  \item The generic function signatures of the DOCUMENTATION symbol do
    9696    not match the CLHS.
    133133apply to strings, integers and floats. Other values need to be converted
    134134to their Java equivalents by the programmer before calling the Java
    135 object method.
     135object method. Java values returned to Lisp are also generally converted
     136back to their Lisp counterparts. Some operators make an exception to this
     137rule and do not perform any conversion; those are the ``raw'' counterparts
     138of certain FFI functions and are recognizable by their name ending with
    137141\subsection{Lowlevel Java API}
    172176Once you have a reference to the method, you can call it using \code{JAVA:JCALL},
    173177which takes the method as the first argument. The second argument is the
    174 object instance to call the method on. Any remaining parameters are used
    175 as the remaining arguments for the call.
     178object instance to call the method on, or \code{NIL} in case of a static method.
     179Any remaining parameters are used as the remaining arguments for the call.
    177181\subsubsection{Calling Java object methods: dynamic dispatch}
    184188select the best matching method and dispatch the call.
    186 % ###TODO document ``intended class''
     190\subsubsection{Dynamic dispatch: caveats}
     192Dynamic dispatch is performed by using the Java reflection API. Generally
     193it works fine, but there are corner cases where the API does not correctly
     194reflect all the details involved in calling a Java method. An example is
     195the following Java code:
     198ZipFile jar = new ZipFile("/path/to/some.jar");
     199Object els = jar.entries();
     200Method method = els.getClass().getMethod("hasMoreElements");
     204even though the method \code{hasMoreElements} is public in \code{Enumeration},
     205the above code fails with
     208java.lang.IllegalAccessException: Class ... can
     209not access a member of class$2 with modifiers
     211       at sun.reflect.Reflection.ensureMemberAccess(
     212       at java.lang.reflect.Method.invoke(
     213       at ...
     216because the method has been overridden by a non-public class and the
     217reflection API, unlike javac, is not able to handle such a case.
     219While code like that is uncommon in Java, it is typical of ABCL's FFI
     220calls. The code above corresponds to the following Lisp code:
     223(let ((jar (jnew "" "/path/to/some.jar")))
     224  (let ((els (jcall "entries" jar)))
     225    (jcall "hasMoreElements" els)))
     228except that the dynamic dispatch part is not shown.
     230To avoid such pitfalls, all Java objects in ABCL carry an extra
     231field representing the ``intended class'' of the object. That is the class
     232that is used first by \code{JAVA:JCALL} and similar to resolve methods;
     233the actual class of the object is only tried if the method is not found
     234in the intended class. Of course, the intended class is always a superclass
     235of the actual class - in the worst case, they coincide. The intended class
     236is deduced by the return type of the method that originally returned
     237the Java object; in the case above, the intended class of \code{ELS}
     238is \code{java.util.Enumeration} because that's the return type of
     239the \code{entries} method.
     241While this strategy is generally effective, there are cases where the
     242intended class becomes too broad to be useful. The typical example
     243is the extraction of an element from a collection, since methods in
     244the collection API erase all types to \code{Object}. The user can
     245always force a more specific intended class by using the \code{JAVA:JCOERCE}
    188248% \begin{itemize}
    202262\subsubsection{Parameter matching for FFI dynamic dispatch}
    205 ...
     264The algorithm used to resolve the best matching method given the name
     265and the arguments' types is the same as described in the Java Language
     266Specification. Any deviance should be reported as a bug.
     268% ###TODO reference to correct JLS section
    207270\section{Lisp from Java}
Note: See TracChangeset for help on using the changeset viewer.