Node:Method operations, Next:Field operations, Previous:Allocating objects, Up:Objects Classes and Modules
You can call a Java method as if it were a Scheme procedure
using various mechanisms.
The most convenient way to do it is to
use define-namespace
to define an alias for a Java class:
(define-namespace Int32 "class:java.lang.Integer")In this example the name
Int32
is a namespace alias
for the namespace whose full name is "class:java.lang.Integer"
.
The full name should be the 6 characters "class:"
followed
by the fully-qualified name of a Java class.
You can name a method using a qualified name containing a colon.
The part of the name before the colon is a namespace alias (in
this case Int32
), and the part of the name after the colon is the
method name. For example:
(Int32:toHexString 255) => ffThis invokes the static method
toHexString
in the
Java class java.lang.Integer
, passing it the argument 255
,
and returning the Java String "ff"
. (Note this is not the
same as a Scheme string!)
You can use the method name new
to construct new objects:
(Int32:new '|255|)This is equivalent to the Java expression
new Integer("255")
.
You can also write:
(Int32:new "255")Kawa is smart enough to convert the Kawa string to a Java String.
You can invoke non-static methods the same way. In that case the first
argument is the receiver or this
argument.
(Int32:toString (Int32:new "00255"))This evaluates to the Java String
"255"
.
As a shorthand, you can use the name of a Java class instead of a namespace alias:
(java.lang.Integer:toHexString 255) (java.lang.Object:toString some-value)If Kawa sees a qualified name with a prefix that is not defined and that matches the name of an existing class, then Kawa will automaticaly treat the prefix as a nickname for namespace uri like
class:java.lang.Integer
.
Both conditions should be true at both compile-time and run-time.
However, using an explicit define-namespace
is recommended.
If you prefer, you can instead use the following functions. (There is also an older deprecated lower-level interface (see Low-level Method invocation.)
invoke-static class name args ... | Function |
The class can be a <java.lang.Class> , a
<gnu.bytecode.ClassType> , or a <symbol> or <string>
that names a Java class. The name can be <symbol> or
<string> that names one or more methods in the Java class.
The name is "mangled" (see Mangling) into a valid Java name.
Any public methods (static or instance) in the specified class (or its
super-classes) that match "name" or "name$V" collectively form a
generic procedure. When the procedure is applied to the argument list,
the most specific applicable method is chosen depending on the
argument list; that method is then
called with the given arguments. Iff the method is an instance method,
the first actual argument is used as the ("name$V" is used for procedures with An example (derived from the Skij FAQ): (invoke-static <java.lang.Thread> 'sleep 100) The behavior of interpreted code and compiled code is not
identical, though you should get the same result either way
unless you have designed the classes rather strangely. The
details will be nailed down later, but the basic idea is that
the compiler will "inline" the |
invoke object name args ... | Function |
The name can be <symbol> or
<string> that names one or more methods in the Java class.
The name is "mangled" (see Mangling) into a valid Java name.
Any public methods (static or instance) in the specified class (or its
super-classes) that match "name" or "name$V" collectively form a
generic procedure. When the procedure is applied to the argument list,
the most specific applicable method is chosen depending on the
argument list; that method is then
called with the given arguments. Iff the method is an instance method,
the object is used as the ("name$V" is used for procedures with The behavior of interpreted code and compiled code is not
indentical, though you should get the same result either way
unless you have designed the classes rather strangely. The
details will be nailed down later, but the basic idea is that
the compiler will "inline" the If the compiler cannot determine the method to call (assuming the method name is constant), the compiler has to generate code at run-time to find the correct method. This is much slower, so the compiler will print a warning. To avoid a waning, you can use a type declaration, or insert a cast: (invoke (as <java.util.Date> my-date) 'setDate cur-date)or (let ((my-date :: <java.util.Date> (calculate-date)) (cur-date :: <int> (get-cur-date))) (invoke my-date 'setDate cur-date)) |
invoke-special class receiver-object name arg ... | Function |
The class can be a <java.lang.Class> , a
<gnu.bytecode.ClassType> , or a <symbol> or <string>
that names a Java class.
The name can be <symbol> or
<string> that names one or more methods in the Java class.
The name is "mangled" (see Mangling) into a valid Java name.
This procedure is very similar to Any methods in the specified class that match "name" or
"name$V" collectively form a generic procedure. That generic
procedure is then applied as in The compiler must be able to inline this procedure (because you cannot force a specific method to be called using reflection). Therefore the class and name must resolve at compile-time to a specific method. (define-simple-class <MyClass> (<java.util.Date>) ((get-year) :: <int> (+ (invoke-special <java.util.Date> (this) 'get-year)) 1900) ((set-year (year :: <int>)) :: <void> (invoke-special <java.util.Date> (this) 'set-year (- year 1900)))) |
class-methods class name | Function |
Return a generic function containing those methods of class
that match the name name, in the sense of invoke-static .
Same as:
(lambda args (apply invoke-static (cons class (cons name args)))) |
Some examples using these functions are vectors.scm
and characters.scm
the directory kawa/lib
in
the Kawa sources.