I'm having trouble passing a method reference into...
# getting-started
h
I'm having trouble passing a method reference into a Kotlin function. What's weird is it works if I declare and pass it from Kotlin, but if I declare/pass from Java I get a compile error. The type resolves correctly in the first line, but it complains in the second line, even though the type I'm passing looks like it should meet all variance requirements. I verified that all imports are correct, and, again, it works in an equivalent Kotlin file. Any ideas? (Note that the type
Pair<List<String>, String>
is just for testing purposes and is not final.)
e
the Kotlin type
Copy code
(Pair<List<String>, String>, Boolean) -> Boolean
should translate to the Java type
Copy code
Function2<? extends Pair<? extends List<? extends String>, ? extends String>, ? extends Boolean, ? super Boolean>
h
Shouldn't it translate to
? super Pair
and
? super Boolean
, since
Function2
has variance
<in, in, out>
? Either way, though, I'm passing in the exact types required, so variance shouldn't even matter. That's why I'm confused.
e
oh yes, I got it backwards for Function
the thing is, in Java
List<String>
is not a subtype of
List<? extends String>
etc.
h
Why not? I'm almost certain it is, and this is confirmed by the Kotlin docs on variance and the Wikipedia page for Java's wildcard type.
Update:
List<Pair<String, String>>
works fine, but
Pair<List<String>, String>
does not. Furthermore, if I take List out of the equation entirely with
Pair<Pair<String, String>, String>
everything works. The issue happens if I replace List with Lazy (Lazy was my original intended type), so it appears to be an issue with invariant types.
Okay, I think I figured it out. I wasn't thinking things through fully. All type translations are happening properly. The issue is that the
run
function is defined in Java code, so I'm actually trying to go backward from ? extends T back to just T, which is not safe. In other words, the variance information is lost along the way. Furthermore, while it is true that
List<String>
is a subtype of
List<? extends String>
is, it is of course not a supertype, which is required by the Kotlin function, so when the variance info is lost in the Java code, problems ensue. Moral of the story is variance is still extremely confusing. @ephemient thanks for your help!