## Calling Java methods from Scheme

You can call a Java method as if it were a Scheme procedure using various mechanisms.

### Calling static methods using colon notation

The easiest way to invoke a static method is to use colon notation, specifically:

`(``class-expression``:``method-name` `argument` ...`)`

The `class-expression` can be a class in the current lexical scope, such as a class defined using `define-simple-class`:

    (define-simple-class MyClass ()
      ((add2 x y) allocation: 'static (+ x y)))
    (MyClass:add2 3 4) ⇒ 7

Often `class-expression` is a fully-qualified class name:

    (java.lang.Math:sqrt 9.0) ⇒ 3.0

This is only allowed when the name is of a class that exists and is accessible both at compile-time and run-time, and the name is not otherwise lexically bound.

You can also use a defined alias:

    (define-alias jlMath java.lang.Math)
    (jlMath:sqrt 16.0) ⇒ 4.0

You can even evaluate `class-expression` at run-time (in which case Kawa may have to use slower reflection):

    (let ((math java.lang.Math)) math:sqrt 9.0) ⇒ 3.0

Here `java.lang.Math` evaluates to a `java.lang.Class` instance for the named class (like Java’s `java.lang.Class.class`, again assuming the class exists and is accessible both at compile-time and run-time, and the name is not otherwise lexically bound.

### Calling instance methods using colon notation

The syntax is:

`(``instance``:``method-name` `argument` ...`)`

This invokes the method named `method-name` with the evaluated `instance` as the target object and the evaluated `argument`s as the method arguments.

For example:

    ((list 9 8 7):toString) ⇒ "(9 8 7)"
    ([5 6 7]:get 2) ⇒ 7

This older syntax is also available:

`(*:``method-name` `instance` `argument` ...`)`

For example:

    (*:toString (list 9 8 7))

You can also name the class explicitly:

`(``class-expression``:``method-name` `instance` `argument` ...`)`

For example:

    (java.util.List:get [5 6 7] 2) ⇒ 7

Using an explicit class is like coercing the `instance`:

`(*:``method-name` `(as` `class-expression` `instance` `)``argument` ...`)`

Note that for some special values, including `java.lang.Class` instances, you can’t use the compact form of colon notation where the `instance` is before the comma:

    (java.lang.Integer:getDeclaredField "MAX_VALUE") ⇒ error

This is because in this case we look for a static member of `java.lang.Integer` (at least as currently defined and implemented), while we want an instance member of `java.lang.Class`. In those cases you can use one of these alternative forms, which all return the same `java.lang.reflect.Field` result:

    (*:getDeclaredField java.lang.Integer "MAX_VALUE")
    (java.lang.Class:getDeclaredField java.lang.Integer "MAX_VALUE")
    (invoke java.lang.Integer 'getDeclaredField "MAX_VALUE")

### Method names

The method to invoke is selected using the specified method name and argments. If specified name is not a Java name, it is "mangled" (see Mangling) into a valid Java name. All accessible methods whose names match are considered. Methods that match after appending `$V` or `$X` or `$V$X` are also considered. A `$V` suffix matches a variable number of arguments: any excess arguments are collect into an `gnu.lists.LList` or a Java array (depending on the final parameter type). A `$X` specifies that the method expects an extra implicit `CallContext` parameter. In that case the method’s result is written to the `CallContext`, so the method result type must be `void`.

(Kawa may compile a procedure with a `#!rest` or keyword args whose name is ``fn`` to a method named ``fn`$V`. It adds an implicit parameter for the extra arguments. By default this extra extra parameter is a Scheme list. You can specify a Java array type instead, in which case the method is named ``fn`` without the `$V`, and instead it is marked as a Java-5 varargs method. The array element type must be compatible with all the extra arguments.)

### Invoking a method with the `invoke` function

If you prefer, you can instead use the following functions. (There is also an older deprecated lower-level interface (see Low-level Method invocation.)

Procedure: `invoke-static` `class` `name` `args` `...`

> 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.

> Any accessible 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 `this` argument. If there are no applicable methods (or no methods at all!), or there is no "best" method, `WrongType` is thrown.

> An example:

>     (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-static` call if it can pick a single "best" matching method.

Procedure: `invoke` `object` `name` `args` `...`

> The `name` can be `<symbol>` or `<string>` that names one or more methods in the Java class.

> Any accessible 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 `this` argument; otherwise `object` is prepended to the `args` list. If there are no applicable methods (or no methods at all!), or there is no "best" method, `WrongType` is thrown.

> 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 `invoke-static` call if it can pick a single "best" matching method.

> 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))

Procedure: `invoke-special` `class` `receiver-object` `name` `arg` `...`

> 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.

> This procedure is very similar to `invoke` and `invoke-static` and invokes the specified method, ignoring any methods in subclasses that might overide it. One interesting use is to invoke a method in your super-class like the Java language `super` keyword.

> 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 `invoke` using the `receiver-object` and the arguments (if any).

> 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))))

Procedure: `class-methods` `class` `name`

> 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.

### Using a namespace prefix

This way of invoking a method is deprecated.

You can 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.

Instead of a `vamespace-uri` you can use a variable that names a class, usually of the form `<`classname`>`. The following is equivalent to the above:

    (define-namespace Int32 <java.lang.Integer>)

However, there is one important difference: The `<`classname`>` is first searched in the lexical scope. It may resolve to a class defined in the current compilation unit (perhaps defined using `define-simple-class`), or imported from another module, or an alias (such as from `define-alias`). Only if `<`classname`>` is not found in the current scope is it tried as the class name `classname`.

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) ⇒ "ff"

This invokes the static method `toHexString` in the Java class `java.lang.Integer`, passing it the argument `255`, and returning the String `"ff"`.

The general syntax is

    (prefix:method-name arg ...)

This invokes the method named `method-name` in the class corresponding to `prefix`, and the `arg`s are the method arguments.

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")

You can also call instance methods using a namespace prefix:

    (Int32:doubleValue (Int32:new "00255"))

This returns the `double` value `255.0`.

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 a known class, then Kawa will automatically 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.

As a final shorthand you can use an identifier in handle brackets, such as an existing type alias like `<list>`. The following are all equivalent:

    (<list>:list3 'a 'b 'c)

This is equivalent to:

    (define-namespace prefix <list>
    (prefix:list3 'a 'b 'c)

for some otherwise-unused `prefix`.