6.65. kink/javahost/JAVA

Provides a way to operate on Java objects, values, classes and methods.

Host system integration provided by JAVA module is meant to be seamfull. There is a clear boundary between Kink world and Java world. For example, a Java method cannot be called directly as a Kink function like JRuby or Groovy. Instead, you have to use .call_method:

Java_obj.call_method('toString')

There are several reasons behind the design.

1) Kink is fundamentally different from Java, both in the object system and the execution semantics. Thus, seamless integration is hard to achieve.

2) Generally, larger applications can be designed more simply when there is a boundary between separate systems.

3) With a clear boundary, Kink can evolve independent of Java.

Typable-as

Here we define a binary relation, typable-as, between a Java object reference and a Java class object.

When an object reference `R` is typable-as a class object `T`, one of the following conditions is met:

• `T` is a class object of a reference type, and `R` is an instance of the reference type.

• `T` is a class object of a reference type, and `R` is null.

• `R` is an instance of Boolean, Character, Byte, Short, Integer, Long, Float, or Double, and `T` is a class object of the corresponding primitive type.

Hereinafter, we refer to a class object and the type which the class object represents interchangeably.

6.65.1. type java

A `java` value is a pair of (objectReference, type), where `objectReference` is a Java object reference, and `type` is a class object.

`type` is used to look up Java instance methods and instance fields.

Invariant

`objectReference` must be typable-as `type`.

6.65.1.1. J.type

`type` method returns the `type` attribute of `J`.

The result of `type` method is a `java` value (t, java.lang.Class), where `t` is `type` attribute of `J`.

Example

:JAVA.require_from('kink/javahost/')

:Comparable_class <- JAVA.class('java.lang.Comparable')
:Type <- JAVA.string('foo').as(Comparable_class).type
stdout.print_line(Type.repr) # => (java "interface java.lang.Comparable" as java.lang.Class)

6.65.1.2. J.as(New_type)

`as` changes `type` to `New_type`.

The result of `as` is a `java` value (ref, nt), where `ref` is `objectReference` of `J`, and `nt` is `objectReference` of `New_type`.

Preconditions

`New_type` must be a `java` value (nt, *), where `nt` is a class object, and `objectReference` of `J` is typeable-as `nt`.

Example

:JAVA.require_from('kink/javahost/')
:Integer_class <- JAVA.class('java.lang.Integer')

:Int <- JAVA.int(42)
stdout.print_line(Int.repr)                   # => (java "42" as int)
stdout.print_line(Int.as(Integer_class).repr) # => (java "42" as java.lang.Integer)

6.65.1.3. J.instance_of?(Klass)

`instance_of?` returns whether `objectReference` of `J` is an instance of `Klass`. The check is equivalent to instanceof operator of Java language.

Precondition

`Klass` must be a `java` value (klass, *), where `klass` is an instance of java.lang.Class.

Example

:JAVA.require_from('kink/javahost/')
:Integer_class <- JAVA.class('java.lang.Integer')
:String_class <- JAVA.class('java.lang.String')
:Object_class <- JAVA.class('java.lang.Object')

stdout.print_line(JAVA.string('foo').instance_of?(String_class).repr)   # => true
stdout.print_line(JAVA.string('foo').instance_of?(Object_class).repr)   # => true
stdout.print_line(JAVA.string('foo').instance_of?(Integer_class).repr)  # => false

stdout.print_line(JAVA.int(42).instance_of?(Integer_class).repr)  # => true
stdout.print_line(JAVA.int(42).instance_of?(Object_class).repr)   # => true
stdout.print_line(JAVA.int(42).instance_of?(JAVA.int_class).repr) # => false

6.65.1.4. J.eq_eq?(Another)

`eq_eq?` returns whether `objectReference` attributes of `J` and `Another` are identical in the meaning of `==` operator of Java language.

Precondition

`Another` must be a `java` value.

Example

:JAVA.require_from('kink/javahost/')

# null is eq_eq? null, irrespective of their types
:Null_string <- JAVA.null.as(JAVA.class('java.lang.String'))
:Null_integer <- JAVA.null.as(JAVA.class('java.lang.Integer'))
stdout.print_line(Null_string.eq_eq?(Null_integer).repr)  # => true

:Object_class <- JAVA.class('java.lang.Object')
:Str <- JAVA.string('foobar')
:Str_as_obj <- Str.as(Object_class)

# object is eq_eq? itself, irrespective their types
stdout.print_line(Str.eq_eq?(Str_as_obj).repr)        # => true

# object is not eq_eq? another object
stdout.print_line(Str.eq_eq?(Object_class.new).repr)  # => false

6.65.1.5. J.null?

`null?` returns whehter `objectReference` attribute of `J` is null.

6.65.1.6. J.to_kink_str

`to_kink_str` returns a `str` value from a Java string.

Precondition

`objectReference` of `J` must be an instance of java.lang.String.

Example

:JAVA.require_from('kink/javahost/')

:Java_string <- JAVA.string('foobar')
:Kink_str <- Java_string.to_kink_str
stdout.print_line(Kink_str.repr)  # => "foobar"

6.65.1.7. J.to_kink_bool

`to_kink_bool` returns a `bool` value from a Java boolean.

Precondition

`objectReference` of `J` must be an instance of java.lang.Boolean.

Example

:JAVA.require_from('kink/javahost/')

:Empty <- JAVA.string('')
:Non_empty <- JAVA.string('foo')
stdout.print_line(Empty.call_method('isEmpty').to_kink_bool.repr)     # => true
stdout.print_line(Non_empty.call_method('isEmpty').to_kink_bool.repr) # => false

6.65.1.8. J.to_kink_num

`to_kink_num` returns a `num` value from a Java number.

Conversion from Character, Byte, Short, Integer, Long, or BigInteger

If `objectReference` of `J` is a Character, Byte, Short, Integer, Long or BigInteger, `Scale` of the result `num` will be 0, and `Mantissa` of the result `num` will be equal to the integer.

Conversion from Float or Double

If `objectReference` of `J` is a Float or Double, `Scale` of the result `num` will be the minimum non-negative integer on which the number can be exactly expressed, and `Mantissa` of the result `num` will be `J * (10 ^ Scale)`.

The sign of 0 is not preserved in the result.

Conversion from BigDecimal

If `objectReference` of `J` is a BigDecimal, `Scale` of the result `num` will be equal to the result of BigDecimal.scale(), and `Mantissa` will be equal to the result of BigDecimal.unscaledValue().

Preconditions

`objectReference` of `J` must be an instance of Character, Byte, Short, Integer, Long, Float, Double, BigInteger or BigDecimal.

If the reference is a Float or Double, it must not be NaN or plus/minus infinite numbers.

If the reference is a BigInteger, it must be in the supported range of `Mantissa` of `num` values.

If the reference is a BigDecimal, its scale must be in the range of supported `Scale` of `num` values, and its unscaled value must be in the range of supported `Mantissa` of `num` values.

Example

:JAVA.require_from('kink/javahost/')

:Ans <- JAVA.byte(42).to_kink_num
stdout.print_line(Ans.repr)           # => 42
stdout.print_line(Ans.scale.repr)     # => 0
stdout.print_line(Ans.mantissa.repr)  # => 42

:Pi <- JAVA.float(3.14).to_kink_num
stdout.print_line(Pi.repr)          # => 3.1400001049041748046875
stdout.print_line(Pi.scale.repr)    # => 22
stdout.print_line(Pi.mantissa.repr) # => 31400001049041748046875

6.65.1.9. J.to_kink_bin(...[From To])

`to_kink_bin` returns a `bin` value from a Java byte array.

The default value of `From` is 0. The default value of `To` is the length of the byte array.

The size of the result `bin` will be `To - From`. The `bin` will contain a slice of bytes of `J` in the range [From, To).

Preconditions

`J` must be a `java` value (bytes, *) where `bytes` is an instance of byte[].

`From` and `To` must be integer `num` values.

0 <= From <= To <= bytes.length

Example

:JAVA.require_from('kink/javahost/')

:Bytes <- JAVA.byte_class.array_of(
  JAVA.byte(0) JAVA.byte(1) JAVA.byte(2) JAVA.byte(3) JAVA.byte(4))
:Copy <- Bytes.to_kink_bin
stdout.print_line(Copy.repr) # => (bin 0x00 0x01 0x02 0x03 0x04)

:Slice <- Bytes.to_kink_bin(1 4)
stdout.print_line(Slice.repr) # => (bin 0x01 0x02 0x03)

6.65.1.10. J.to_kink_exception

`to_kink_exception` returns an `exception` value from a Java Throwable.

`to_kink_exception` encodes Throwable.toString into `Message`, Throwable.getStackTrace into `Traces`, Throwable.getCause and getSuppressed into `Next` of the result `exception`.

Other attributes of the throwable, like SQLException.getErrorCode, are not preserved.

Preconditions

`objectReference` of `J` must be an instance of java.lang.Throwable.

Example

:JAVA.require_from('kink/javahost/')

JAVA.big_integer(42).call_method('divide' JAVA.big_integer(0)){(:C)
  C.catch(JAVA.class('java.lang.ArithmeticException')){(:Java_exc)
    :Exc = Java_exc.to_kink_exception
    Exc.desc_iter.each{(:Str)
      stdout.print_line(Str)
    }
  }
}
# Output:
#   -- main exception
#   [org.kink_lang.kink/org.kink_lang.kink.internal.startup.Kink.main(Kink.java:34)]
#   [org.kink_lang.kink/org.kink_lang.kink.Vm.run(Vm.java:217)]
#   ,,,
#   [java.base/java.math.BigInteger.divideKnuth(BigInteger.java:2447)]
#   [java.base/java.math.MutableBigInteger.divideKnuth(MutableBigInteger.java:1184)]
#   java.lang.ArithmeticException: BigInteger divide by zero

6.65.1.11. J.unwrap

`unwrap` extracts a Kink value wrapped by JAVA.wrap.

When `J` is a `java` value (Wrapped, ? super org.kink_lang.kink.Val), `unwrap` returns `Wrapped`.

Preconditions

`J` must be a `java` value (Wrapped, *), where `Wrapped` is an instance of org.kink_lang.kink.Val, and the runtime of `Wrapped` is same as the current runtime.

Example

:JAVA.require_from('kink/javahost/')
:VAL.require_from('kink/')

:Str <- 'foo'
:Wrapped_str <- JAVA.wrap(Str)
stdout.print_line(Wrapped_str.repr)  # (java "StrVal(foo)" as org.kink_lang.kink.Val)

:Unwrapped_str <- Wrapped_str.unwrap
stdout.print_line(Unwrapped_str.repr) # => "foo"
stdout.print_line(VAL.same?(Unwrapped_str Str).repr) # => true

6.65.1.12. J.array_class

`array_class` returns the class object of the array class of the given component type.

If `objectReference` of `J` is a class object `C`, `array_class` returns a `java` value (C[], java.lang.Class).

Preconditions

`J` must be a `java` value (C, *), where `C` is a class object.

`C` must not be void class.

If `C` is an array class, its dimension must not exceed 254.

Example

:JAVA.require_from('kink/javahost/')

:Array_class <- JAVA.int_class.array_class
stdout.print_line(Array_class.repr)  # => (java "class [I" as java.lang.Class)

6.65.1.13. J.array_new(Size)

`array_new` returns an array of the given component type and the size.

If `objectReference` of `J` is a class object `C`, `array_new` returns a `java` value of (Array, C[]), where `Array` is an array with `Size` as the length.

The elements `Array` is initialized by the zero value of `C`.

Preconditions

`J` must be a `java` value (C, *), where `C` is a class object.

`C` must not be void class.

If `C` is an array class, its dimension must not exceed 254.

`Size` must be a non-negative integer `num`.

Example

:JAVA.require_from('kink/javahost/')

:Array <- JAVA.int_class.array_new(2)
stdout.print_line(Array.repr)               # => (java "[I@4722ef0c" as [I)
stdout.print_line(Array.array_length.repr)  # => 2

6.65.1.14. J.array_of(...[E0 E1 ,,,])

`array_of` returns an array containing the given elements.

If `objectReference` of `J` is a class object `C`, `array_of` returns a `java` value of (Array, C[]), where `Array` is an array containing `E0`, `E1`, ,,, as its elements.

Preconditions

`J` must be a `java` value (C, *), where `C` is a class object.

`C` must not be void class.

If `C` is an array class, its dimension must not exceed 254.

`E0`, `E1`, ,,, must be `java` values whose `objectReference` attributes are typable-as `objectReference` of `J`.

Example

:JAVA.require_from('kink/javahost/')

:Array <- JAVA.int_class.array_of(JAVA.int(10) JAVA.int(20))
stdout.print_line(Array.repr)               # => (java "[I@4722ef0c" as [I)
stdout.print_line(Array.array_get(0).repr)  # => (java "10" as int)
stdout.print_line(Array.array_get(1).repr)  # => (java "20" as int)
stdout.print_line(Array.array_length.repr)  # => 2

6.65.1.15. J.array_length

`array_length` returns the length of array as an integer `num` value.

Precondition

`J` must be a `java` value (array, *), where `array` is an array.

6.65.1.16. J.array_get(Ind)

`array_get` returns the element of the array `J` at the index `Ind`.

If the component type of the array is a reference type `rt`, `array_get` returns a `java` value (element, rt), where `element` is the element of the array.

If the component type of the array is a primitive type `pt`, `array_get` returns a `java` value (box, pt), where `box` is a instance of the corresponding wrapper type which contains the element of the array.

Preconditions

`J` must be a `java` value (array, *), where `array` is an array.

`Ind` must be an integer `num` value in the range [0, length), where `length` is the length of the array.

6.65.1.17. J.array_set(Ind Elem)

`array_set` sets the value `Elem` to the array `J` at the index `Ind`.

Preconditions

`J` must be a `java` value (array, *), where `array` is an array.

`Ind` must be an integer `num` value in the range [0, length), where `length` is the length of the array.

`Elem` must be a `java` value (elem, *), where `elem` is typable-as the component type of the array.

6.65.1.18. J.get_field(Field_name)

`get_field` returns the content of the public instance field.

The field is looked up from `type` of `J`, using Class.getField(String).

If the declared type of the field is a reference type `rt`, the result will be a `java` value (contentObj, rt), where `contentObj` is the content of the field.

If the declared type of the field is a primitive type `pt`, the result will be a `java` value (box, pt), where `box` is an instance of the corresponding wrapper type which contains the element of the field.

Preconditions

`J` must be a `java` value.

`Field_name` must be a `str`.

`type` of `J` must have a public instance field with the name `Field_name`.

Example

:JAVA.require_from('kink/javahost/')

:True <- JAVA.runtime.get_field('bool').get_field('trueVal')
stdout.print_line(True.repr) # => (java "trueVal" as org.kink_lang.kink.Val)

6.65.1.19. J.set_field(Field_name Content)

`set_field` sets `Content` to the public instance field.

The field is looked up from `type` of `J`, using Class.getField(String).

Preconditions

`J` must be a `java` value.

`Field_name` must be a `str`.

`type` of `J` must have a public instance field with the name `Field_name`.

The field must not be final.

`Content` must be a `java` value (contentObj, *), where `contentObj` must be typable-as the declared type of the field.

6.65.1.20. J.get_static(Field_name)

`get_static` returns the content of the public static field of the class `J`.

When `objectReference` of `J` is a class object `ownerClass`, the field is looked up from `ownerClass` using Class.getField(String).

If the declared type of the field is a reference type `rt`, the result will be a `java` value (contentObj, rt), where `contentObj` is the content of the field.

If the declared type of the field is a primitive type `pt`, the result will be a `java` value (box, pt), where `box` is an instance of the corresponding wrapper type which contains the element of the field.

Preconditions

`J` must be a `java` value (ownerClass, *), where `ownerClass` is an instance of java.lang.Class.

`Field_name` must be a `str`.

`ownerClass` must have a public static field with the name `Field_name`.

Example

:JAVA.require_from('kink/javahost/')

:Byte_class <- JAVA.class('java.lang.Byte')
:Byte_max <- Byte_class.get_static('MAX_VALUE')
stdout.print_line(Byte_max.repr)  # => (java "127" as byte)

6.65.1.21. J.set_static(Field_name Content)

`set_static` sets `Content` to the public static field of the class `J`.

When `objectReference` of `J` is a class object `ownerClass`, the field is looked up from `ownerClass` using Class.getField(String).

Preconditions

`J` must be a `java` value (ownerClass, *), where `ownerClass` is an instance of java.lang.Class.

`Field_name` must be a `str`.

`ownerClass` must have a public static field with the name `Field_name`.

The field must not be final.

`Content` must be a `java` value (contentObj, *), where `contentObj` must be typable-as the declared type of the field.

6.65.1.22. J.call_method(Method_name ...[A0 A1 ,,,] ...[$config={}])

`call_method` calls a public instance method of the object `J`.

Look up

The instance method is looked up by `J.type.getMethod(Method_name, A0.type, A1.type, ,,,)`.

Result

1) If the declared return type of the method is a reference type `rt`, and the method terminates without throwing an exception, `call_method` tail-calls the success continuation with a `java` value (resultObj, rt), where `resultObj` is the returned value of the method.

2) If the declared return type `pt` of the method is char, boolean, byte, short, int, long, float or double, and the method terminates without throwing an exception, `call_method` tail-calls the success continuation with a `java` value (resultObj, pt), where `resultObj` is a wrapper instance of the returned value.

3) If the declared return type the method is void, and the method terminates without throwing an exception, `call_method` tail-calls the success continuation with no arg.

4) If the method terminates throwing a Java exception `exceptionObj`, and the exception is an instance of one or more exception types specified by invocations of C.catch, `call_method` tail-calls the error continuation corresponding to the most specific exception type `et` with a `java` value (exceptionObj, et).

5) If the method terminates throwing a Java exception, and no exception type passed to C.catch matches the thrown exception, `call_method` raises a Kink exception.

If C.on_success is not called for the config value, and the declared return type of the method is void, { nada } is used as the default success continuation.

If C.on_success is not called for the config value, and the declared return type of the method is not void, VAL.identity is used as the default success continuation.

Preconditions

`Method_name` must be a `str`.

`A0`, `A1` ,,, must be `java` values.

`type` of `J` must have the specified public instance method.

$config must be a function which takes a `java_call_config` value.

Examples

:JAVA.require_from('kink/javahost/')
:ArrayList_class <- JAVA.class('java.util.ArrayList')
:Object_class <- JAVA.class('java.lang.Object')
:Lst <- ArrayList_class.new

# .as(Object_class) is required,
# because the method is looked up using static types of the args
Lst.call_method('add' JAVA.string('foo').as(Object_class))
Lst.call_method('add' JAVA.int(42).as(Object_class))

stdout.print_line(Lst.repr) # => (java "[foo, 42]" as java.util.ArrayList)

# call ArrayList.remove(int)
:Removed <- Lst.call_method('remove' JAVA.int(0))
stdout.print_line(Removed.repr) # => (java "foo" as java.lang.Object)

# call ArrayList.remove(java.lang.Object)
:Success <- Lst.call_method('remove' JAVA.int(42).as(Object_class))
stdout.print_line(Success.repr) # => (java "true" as boolean)

By default, a Java exception results in a Kink exception.

:CONTROL.require_from('kink/')
:JAVA.require_from('kink/javahost/')
:ArrayList_class <- JAVA.class('java.util.ArrayList')
:Lst <- ArrayList_class.new

CONTROL.try(
  { Lst.call_method('get' JAVA.int(42)) }
  {(:R) raise('must not reach here') }
  {(:Exc)
    stdout.print_line(Exc.message)
  }
)
# => java exception: java.lang.IndexOutOfBoundsException: Index 42 out of bounds for length 0

The success/error continuations can be configured by the config function.

:JAVA.require_from('kink/javahost/')
:BigInteger_class <- JAVA.class('java.math.BigInteger')

:divide_10_by <- {(:Divisor)
  BigInteger_class.get_static('TEN').call_method('divide' Divisor){(:C)
    C.on_success{(:R)
      'result: {}'.format(R.repr)
    }
    C.catch(JAVA.class('java.lang.RuntimeException')){(:Exc)
      'rte: {}'.format(Exc.repr)
    }
    C.catch(JAVA.class('java.lang.Exception')){(:Exc)
      'exception: {}'.format(Exc.repr)
    }
  }
}

stdout.print_line(divide_10_by(JAVA.big_integer(2)))
# => result: (java "5" as java.math.BigInteger)

stdout.print_line(divide_10_by(JAVA.big_integer(0)))
# => rte: (java "java.lang.ArithmeticException: BigInteger divide by zero" as java.lang.RuntimeException)

If the return type of the Java method is void, the success continuation is tail-called with no arg.

:JAVA.require_from('kink/javahost/')
:ArrayList_class <- JAVA.class('java.util.ArrayList')
:Object_class <- JAVA.class('java.lang.Object')

:Lst <- ArrayList_class.new
Lst.call_method('add' JAVA.string('foo').as(Object_class))
Lst.call_method('add' JAVA.string('bar').as(Object_class))

Lst.call_method('clear'){(:C)
  C.on_success{()
    stdout.print_line('cleared!')
  }
}
# => cleared!

6.65.1.23. J.call_static(Method_name ...[A0 A1 ,,,] ...[$config={}])

`call_static` calls a public static method of the class `J`.

Look up

When `objectReference` of `J` is a class object `ownerClass`, the static method is looked up by `ownerClass.getMethod(Method_name, A0.type, A1.type, ,,,)`.

Result

Same as J.call_method.

Preconditions

`J` must be a `java` value (ownerClass, *), where `ownerClass` is a class object.

`Method_name` must be a `str`.

`A0`, `A1` ,,, must be `java` values.

`ownerClass` must have the specified public static method.

$config must be a function which takes a `java_call_config` value.

Example

:JAVA.require_from('kink/javahost/')

:String_class <- JAVA.class('java.lang.String')
:Object_class <- JAVA.class('java.lang.Object')
:Java_str <- String_class.call_static(
  'format' JAVA.string('ans=%d') Object_class.array_of(JAVA.int(42)))
stdout.print_line(Java_str.repr)  # => (java "ans=42" as java.lang.String)

6.65.1.24. J.new(...[A0 A1 ,,,] ...[$config={}])

`new` calls a public constructor of the class `J`, and returns the new instance.

Look up

When `objectReference` of `J` is a class object `ownerClass`, the public constructor is looked up by `ownerClass.getConstructor(A0.type, A1.type, ,,,)`.

Result

1) If a new instance `resultObj` is created, `new` tail-calls the success continuation with a `java` value (resultObj, ownerClass).

2) If the constructor terminates throwing a Java exception `exceptionObj`, and the exception is an instance of one or more exception types specified by invocations of C.catch, `new` tail-calls the error continuation corresponding to the most specific exception type `et` with a `java` value (exceptionObj, et).

3) If the constructor terminates throwing a Java exception, and no exception type passed to C.catch matches the thrown exception, `new` raises a Kink exception.

If C.on_success is not called for the config value, VAL.identity is used as the default success continuation.

Preconditions

`J` must be a `java` value (ownerClass, *), where `ownerClass` is a class object.

`A0`, `A1` ,,, must be `java` values.

`ownerClass` must have the specified public constructor.

$config must be a function which takes a `java_call_config` value.

Example

:CONTROL.require_from('kink/')
:JAVA.require_from('kink/javahost/')
:BigDecimal_class <- JAVA.class('java.math.BigDecimal')

:make_big_decimal <- {(:Str)
  BigDecimal_class.new(JAVA.string(Str))
}

stdout.print_line(make_big_decimal('12.3').repr)  # => (java "12.3" as java.math.BigDecimal)

CONTROL.try(
  { make_big_decimal('xxx') }
  {(:R) raise('must not reach here') }
  {(:Exc)
    stdout.print_line(Exc.message)
  }
)
# => java exception: java.lang.NumberFormatException: Character x is neither a decimal digit number, decimal point, nor "e" notation exponential mark.

6.65.2. type java_call_config

`java_call_config` is a config value of J.call_method, J.call_static, and J.new.

6.65.2.1. C.on_success($success)

`on_success` specifies $success as the success continuation.

6.65.2.2. C.catch(Exception_class $error)

`catch` specifies $error as the error continuation corresponding to the exception type `Exception_class`.

`catch` can be called multiple times to specify error continuations for different exception types.

Preconditions

`Exception_class` must be a `java` value (et, *), where `et` is a subclass of java.lang.Throwable.

`Exception_class` must not be a subtype of exception types specified by preceding invocations of `catch`.

$error must be a function which takes a `java` value.

6.65.3. JAVA.is?(Val)

`is?` returns whether `Val` is a `java` value.

6.65.4. JAVA.string(Str)

`string` returns a Java string which has the same string as `Str`.

The result will be a `java` value (string, java.lang.String), where `string` is an instance of String which has the same string as `Str`.

Precondition

`Str` must be a `str` value.

6.65.5. JAVA.bytes(Bin ...[From=0 To=Bin.size])

`bytes` returns a Java byte array from the slice of `Bin` in the range [From, To).

The result will be a `java` value (byteArray, byte[]), where `byteArray` is an array of bytes whose elements are copied from the slice of `Bin` in the range [From, To).

Preconditions

`Bin` must be a `bin`.

`From` and `To` must be integer `num` values.

0 <= From <= To <= Bin.size

6.65.6. JAVA.byte_buffer(Bin)

`byte_buffer` returns a read only ByteBuffer containing the bytes of `Bin`.

The result will be a `java` value (byteBuffer, java.nio.ByteBuffer). `byteBuffer` will have attributes as follows:

• The capacity and the initial limit are Bin.size.

• The initial position is 0.

Precondition

`Bin` must be a `bin`.

6.65.7. JAVA.boolean(Bool)

`boolean` returns a Java boolean corresponding to `Bool`.

If `Bool` is true, `boolean` returns a `java` value (Boolean.TRUE, boolean).

If `Bool` is false, `boolean` returns a `java` value (Boolean.FALSE, boolean).

Precondition

`Bool` must be a `bool`.

6.65.8. JAVA.char(Num)

`char` returns a Java char corresponding to `Num`.

The result will be a `java` value (objectReference=ch, type=char), where `ch` is an instance of java.lang.Character.

Precondition

`Num` must be an integer `num` in the range [0, 0xffff].

6.65.9. JAVA.byte(Num)

`byte` returns a Java byte corresponding to `Num`.

The result will be a `java` value (objectReference=bt, type=byte), where `bt` is an instance of java.lang.Byte.

Precondition

`Num` must be an integer `num` in the range [-128, 127].

6.65.10. JAVA.short(Num)

`short` returns a Java short corresponding to `Num`.

The result will be a `java` value (objectReference=sh, type=short), where `sh` is an instance of java.lang.Short.

Precondition

`Num` must be an integer `num` in the range [- 2**15, 2**15 - 1].

6.65.11. JAVA.int(Num)

`int` returns a Java int corresponding to `Num`.

The result will be a `java` value (objectReference=n, type=int), where `n` is an instance of java.lang.Integer.

Precondition

`Num` must be an integer `num` in the range [- 2**31, 2**31 - 1].

6.65.12. JAVA.long(Num)

`long` returns a Java long corresponding to `Num`.

The result will be a `java` value (objectReference=ln, type=long), where `ln` is an instance of java.lang.Long.

Precondition

`Num` must be an integer `num` in the range [- 2**63, 2**63 - 1].

6.65.13. JAVA.float(Num)

`float` returns a Java float value numerically close to `Num`.

The result will be a `java` value (fl, float), where `fl` is an instance of java.lang.Float, which is converted from `Num` by BigDecimal.floatValue().

Precondition

`Num` must be a `num` value.

6.65.14. JAVA.double(Num)

`double` returns a Java double value numerically close to `Num`.

The result will be a `java` value (dbl, double), where `dbl` is an instance of java.lang.Double, which is converted from `Num` by BigDecimal.doubleValue().

Precondition

`Num` must be a `num` value.

6.65.15. JAVA.big_integer(Num)

`big_integer` returns a Java BigInteger corresponding to `Num`.

The result will be a `java` value (objectReference=bi, type=java.math.BigInteger), where `bi` is an instance of java.math.BigInteger, and the value is equal to `Num`.

Precondition

`Num` must be an integer `num`.

6.65.16. JAVA.big_decimal(Num)

`big_decimal` returns a Java BigDecimal corresponding to `Num`.

The result will be a `java` value (bd, java.math.BigDecimal), where `bd` is an instance of java.math.BigDecimal, whose scale is equal to `Scale` of `Num`, and the unscaledValue is equal to `Mantissa` of `Num`.

Precondition

`Num` must be a `num` value.

6.65.17. JAVA.wrap(Wrapped)

`wrap` returns a `java` value which wraps a Kink value.

`Wrapped` can be a value of any type. `wrap` returns a `java` value (Wrapped, org.kink_lang.kink.Val).

`Wrapped` can be extracted from the result `java` value using `unwrap` method.

Example

:JAVA.require_from('kink/javahost/')

:Str <- 'foo'
:Wrapper <- JAVA.wrap(Str)
stdout.print_line(Wrapper.repr)   # (java "StrVal(foo)" as org.kink_lang.kink.Val)
stdout.print_line(Wrapper.unwrap.repr)  # => "foo"

6.65.18. JAVA.true

`true` returns a `java` value (Boolean.TRUE, boolean).

6.65.19. JAVA.false

`false` returns a `java` value (Boolean.FALSE, boolean).

6.65.20. JAVA.null

`null` returns a `java` value (null, java.lang.Object).

6.65.21. JAVA.runtime

`runtime` returns the current runtime.

The result is a `java` value (vm, org.kink_lang.kink.Vm), where `vm` is the current runtime.

6.65.22. JAVA.boolean_class

`boolean_class` returns a `java` value (boolean.class, java.lang.Class).

6.65.23. JAVA.char_class

`char_class` returns a `java` value (char.class, java.lang.Class).

6.65.24. JAVA.byte_class

`byte_class` returns a `java` value (byte.class, java.lang.Class).

6.65.25. JAVA.short_class

`short_class` returns a `java` value (short.class, java.lang.Class).

6.65.26. JAVA.int_class

`int_class` returns a `java` value (int.class, java.lang.Class).

6.65.27. JAVA.long_class

`long_class` returns a `java` value (long.class, java.lang.Class).

6.65.28. JAVA.float_class

`float_class` returns a `java` value (float.class, java.lang.Class).

6.65.29. JAVA.double_class

`double_class` returns a `java` value (double.class, java.lang.Class).

6.65.30. JAVA.void_class

`void_class` returns a `java` value (void.class, java.lang.Class).

6.65.31. JAVA.class(Class_name ...[$config={}])

`class` looks up a class by the binary name `Class_name`.

Config methods:

• C.on_success($success): default = VAL.identity

• C.on_error($error): default = a function which raises an exception

`class` function loads the specified class, using the reflection access of the unnamed module of the class loader from which org.kink_lang.kink.Vm class of the current runtime is loaded.

If the class `klass` is found, `class` tail-calls $success with a `java` value (klass, java.lang.Class).

If the class is not found, `class` tail-calls $error with no arg.

Preconditions

`Class_name` must be a `str` value.

$success must be a function which takes a `java` value.

$error must be a thunk.