Changeset 13624


Ignore:
Timestamp:
10/10/11 18:33:50 (12 years ago)
Author:
astalla
Message:

Subsection on intended class and a few minor tweaks.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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}
    1010
    1111\maketitle
     
    9393\begin{itemize}
    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.
    9797\end{itemize}
     
    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
     139\code{-RAW}.
    136140
    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.
    176180
    177181\subsubsection{Calling Java object methods: dynamic dispatch}
     
    184188select the best matching method and dispatch the call.
    185189
    186 % ###TODO document ``intended class''
     190\subsubsection{Dynamic dispatch: caveats}
     191
     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:
     196
     197\begin{listing-java}
     198ZipFile jar = new ZipFile("/path/to/some.jar");
     199Object els = jar.entries();
     200Method method = els.getClass().getMethod("hasMoreElements");
     201method.invoke(els);
     202\end{listing-java}
     203
     204even though the method \code{hasMoreElements} is public in \code{Enumeration},
     205the above code fails with
     206
     207\begin{listing-java}
     208java.lang.IllegalAccessException: Class ... can
     209not access a member of class java.util.zip.ZipFile$2 with modifiers
     210"public"
     211       at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:65)
     212       at java.lang.reflect.Method.invoke(Method.java:583)
     213       at ...
     214\end{listing-java}
     215
     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.
     218
     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:
     221
     222\begin{listing-lisp}
     223(let ((jar (jnew "java.util.zip.ZipFile" "/path/to/some.jar")))
     224  (let ((els (jcall "entries" jar)))
     225    (jcall "hasMoreElements" els)))
     226\end{listing-lisp}
     227
     228except that the dynamic dispatch part is not shown.
     229
     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.
     240
     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}
     246operator.
    187247
    188248% \begin{itemize}
     
    202262\subsubsection{Parameter matching for FFI dynamic dispatch}
    203263
    204 
    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.
     267
     268% ###TODO reference to correct JLS section
    206269
    207270\section{Lisp from Java}
Note: See TracChangeset for help on using the changeset viewer.