4.67. kink/javahost/JAVA_PROXY

JAVA_PROXY mod provides a measure to make a Java object whose behavior is defined by Kink code. The java object is created as a Java dynamic proxy (java.lang.reflect.Proxy).

4.67.1. JAVA_PROXY.new(Intfs $handler)

`new` makes a java_val whose behavior is defined by $handler fun.

Precondition:

• `Intfs` must be a vec of java vals, whose object references are instances of java.lang.Class. Those class objects must be of interfaces.

Result

If a Java object is successfully created, the result of `new` is a java_val, whose object reference is the created proxy, and whose static class is the class of the proxy. The created Java object, or a proxy, implements all the specified interfaces.

If object creation fails, `new` raises an exception.

Class loader

The class loader which loads the Kink runtime is used to make a dynamic proxy.

Behavior of the proxy

When a method of the proxy is invoked, $handler is called in a new abstract stack machine, with `Method` and `Args` parameters. See Language specification → Evaluation for the abstract stack machine.

Parameters of $handler:

• `Method` is a java_val (method, java.lang.reflect.Method), where `method` is the invoked method.

• `Args` is a vec of java_val, whose object references are arguments passed to the method, or boxing instances of them, and whose static types are the declared types of the parameters of the method.

Result of $handler:

When $handler terminates throwing an exception, invocation of the Java method throws the Java exception.

When $handler terminates returning a proxy_throw_result val, invocation of the Java method throws the Java exception specified by the proxy_throw_result val. See kink/javahost/PROXY_THROW_RESULT for proxy_throw_result vals.

If the return type of the Java method is void, and $handler terminates returning a val which is not a proxy_throw_result, the Java method returns. In other words, the result of $handler is ignored.

If the return type of the Java method is not void, the result of $handler must be a java_val whose object reference is typable as the return type. The java method returns the object reference, or a primitive value unboxed from the object reference.

Example

:JAVA.require_from('kink/javahost/')
:JAVA_PROXY.require_from('kink/javahost/')
:Runnable_class <- JAVA.class('java.lang.Runnable')
:Run <- JAVA_PROXY.new([Runnable_class]){(:Method :Args)
  Method.call_method('getName').to_kink_str == 'run' || raise(
    'unknown method {}'.format(Method.repr))
  stdout.print_line('hey')
}.as(Runnable_class)
:Thread <- JAVA.class('java.lang.Thread').new([Run])
Thread.call_method('start')
Thread.call_method('join')
# Output:
#   hey