It is dubious whether enhancing the compiler to eliminate reflection for some jcall invocations would be worth the effort. Since Java objects are boxed in ABCL, the compiler would need to generate code to unbox the arguments and box the return value, and place appropriate exception handlers. This would likely increase the size and complexity of the generated code quite a lot. Also, I believe that to optimize a significant number of jcall invocations we need type inference, and that's not an easy task. Of course, the implementation of jcall has to do the very same boxing/unboxing, besides the reflective call itself; it is inevitably less efficient. But I think that, unless your code is made mostly of calls to Java methods, the difference is tolerable.
Naively (=not knowing how it all fits into the bigger ABCL picture), I would expect Java objects not to be boxed and the compiler to be helped by some kind of foreign function declaration. That is, all types are declared statically, dynamic single dispatch should be handled by the JVM. This would mean an initial point of pain (writing the declarations), but elegant usage afterwards. A small script should be able to generate this kind of declarations.
(defjvar foo java.util.StringBuilder) (defjfun sb-to-string java.util.StringBuilder)
(setf foo (new java.util.StringBuilder)) (sb-to-string foo)
Am I making sense or is this off the mark?
The good thing is that any kind of Java calls are always going to be encapsulated inside a lisp interface, so that migrating to something different later is never an issue. I have a feeling that supporting Java's collection APIs (including iterators and Iterable) and Java's streams would be helpful when connecting from ABCL, but I'll have to work some more on my ABCL API for Sesame [1], to be sure.