1 | JSS |
---|
2 | === |
---|
3 | |
---|
4 | Created by Alan Ruttenburg |
---|
5 | |
---|
6 | |
---|
7 | JSS stands for either "Java Simple Syntax" or "Java Syntax Sucks", |
---|
8 | depending on your mood. |
---|
9 | |
---|
10 | The dynamic dispatch of the java.lang.reflect package is used to make |
---|
11 | it real easy, if perhaps less efficient, to write Java code since you |
---|
12 | don't need to be bothered with imports, or with figuring out which |
---|
13 | method to call. The only time that you need to know a class name is |
---|
14 | when you want to call a static method, or a constructor, and in those |
---|
15 | cases, you only need to know enough of the class name that is unique |
---|
16 | wrt to the classes on your classpath. |
---|
17 | |
---|
18 | Java methods look like this: #"toString". Java classes are represented |
---|
19 | as symbols, which are resolved to the appropriate java class |
---|
20 | name. When ambiguous, you need to be more specific. A simple example: |
---|
21 | |
---|
22 | (let ((sw (new 'StringWriter))) |
---|
23 | (#"write" sw "Hello ") |
---|
24 | (#"write" sw "World") |
---|
25 | (print (#"toString" sw))) |
---|
26 | |
---|
27 | What's happened here? First, all the classes in all the jars in the |
---|
28 | classpath have been collected. For each class a.b.C.d, we have |
---|
29 | recorded that b.c.d, b.C.d, C.d, c.d, and d potentially refer to this |
---|
30 | class. In your call to new, as long as the symbol can refer to only |
---|
31 | one class, we use that class. In this case, it is |
---|
32 | java.io.StringWriter. You could also have written (new |
---|
33 | 'io.stringwriter), (new '|io.StringWriter|), (new |
---|
34 | 'java.io.StringWriter)... |
---|
35 | |
---|
36 | the call (#"write" sw "Hello "), uses the code in invoke.java to |
---|
37 | call the method named "write" with the arguments sw and "Hello ". |
---|
38 | JSS figures out the right java method to call, and calls it. |
---|
39 | |
---|
40 | If you want to do a raw java call, use #0"toString". Raw calls |
---|
41 | return their results as Java objects, avoiding doing the usual Java |
---|
42 | object to Lisp object conversions that ABCL does. |
---|
43 | |
---|
44 | (with-constant-signature ((name jname raw?)*) &body body) |
---|
45 | binds a macro which expands to a jcall, promising that the same method |
---|
46 | will be called every time. Use this if you are making a lot of calls and |
---|
47 | want to avoid the overhead of a the dynamic dispatch. |
---|
48 | e.g. (with-constant-signature ((tostring "toString")) |
---|
49 | (time (dotimes (i 10000) (tostring "foo")))) |
---|
50 | runs about 3x faster than (time (dotimes (i 10000) (#"toString" "foo"))) |
---|
51 | |
---|
52 | (with-constant-signature ((tostring "toString" t)) ...) will cause the |
---|
53 | toString to be a raw java call. see get-all-jar-classnames below for |
---|
54 | an example. |
---|
55 | |
---|
56 | Implementation is that the first time the function is called, the |
---|
57 | method is looked up based on the arguments passed, and thereafter |
---|
58 | that method is called directly. Doesn't work for static methods at |
---|
59 | the moment (lazy) |
---|
60 | |
---|
61 | (japropos string) finds all class names matching string |
---|
62 | |
---|
63 | (jcmn class-name) lists the names of all methods for the class |
---|