To work with a Java API, I need to create a method...
# announcements
e
To work with a Java API, I need to create a method whose return type is
Void
and has the following behavior:
Copy code
override fun getResult(): Void {
        if (!success) throw RuntimeException()
    }
This doesn't compile, because a function with a block body requires a return statement.
How can I fix this code?
j
Copy code
override fun getResult(): Unit {
        if (!success) throw RuntimeException()
    }
do you need to return Void explicitly?
k
Doesn't Java also require a return statement?
j
that is kotlin
e
I believe so, because I'm extending
Task<Void>
, which requires implementing
getResult(): Void
.
This compiles, but it's not exactly what I want:
Copy code
override fun getResult(): Void {
        throw RuntimeException()
    }
Sorry, @Ruckus, your code scrolled off my screen, and I missed it at first.
c
In Java,
Void
has a private constructor, so it is impossible to actually get an instance of
Void
. Any method contract that requires you to return
Void
is implicitly requesting you return
null
instead. I think having your Kotlin method have a return type of
Void?
and returning null on the
success
branch is the way to go.
2
e
Yes, @Ruckus, your solution works. I didn't think I'd be able to change the return type. Thank you very much!
s
I’m with James, I assume Kotlin’s Unit to be mapped to Java’s void. So
Copy code
override fun getResult(): Unit {
    if (!success) throw RuntimeException()
}
should work and is more idiomatic than Void?. This playground code overrides Java’s Object’s finalize method which returns void in Java by using Unit and it works fine:
Copy code
class KotlinObject() : java.lang.Object() {
    override fun finalize(): Unit {}
}
https://pl.kotl.in/n_umKF6c8
k
But none of that works if Java code is forcing you to implement
Task<Void>
.
s
It’s interesting that the interop doesn’t automatically translate
Task<Unit>
but it does
Task<Void?>
, because technically
Void?
is as far from
Void
as is
Unit
. (What about ’Nothing?
which is the same set as 'Void?
??) I guess that the instance of
Task<Void?>
is passed back to Java code? Because otherwise using Task<Unit> is probably the answer. Something similar happens when I want to use the
ExecutorService
, which only handles `Callable`s and not `Runable`s. In that case
Callable<Unit>
is the way to go.
c
The difference is that
Task<Unit>
must return something, namely
Unit.INSTANCE
.
Task<Void>
does not make sense, since you cannot get a non-null instance of
Void
to return, and thus
Task<Void?>
must return null
Unit
is analogous to
void
in the sense that it is the default return type, but it is not the same thing as
void
.
void
has no instance,
unit
has an instance and is non-null, and has a different meaning from
void
in Kotlin’s null-safe world