While working on the answer of How does erasure work in Kotlin? I found out some things I did not yet understand, nor did I find any sources why it is that way.
Why is the following not compilable?
fun bar(foo: List<*>) = ""
fun bar(foo: List<*>) = 2
while the following is?
fun bar(foo: List<String>) = ""
fun bar(foo: List<Int>) = 2
For me it even gets more curious, when adding a generic type that isn’t even used, i.e. the following compiles too:
fun bar(foo: List<*>) = ""
fun <T> bar(foo: List<*>) = 2 // T isn't even used
As the last one doesn’t even use T and as we know, generics are erased at runtime, why does this one work, while the variant without generic type does not?
Within the byte code methods only differing in return type are allowed (already described in the above linked answer).
Any hints, sources and/or references are welcome.
Not so sure whether this is a deliberate language design choice or a bug… feel free to move the topic.
While I don’t have an answer, I have a follow up question. Is there a way in Kotlin to invoke both of those functions? Or will always the same one be invoked? Or is there a compile-error when trying to invoke them?
When calling from Java, sometimes it can match the type param and you don’t get ambiguity issues. But sometimes it can’t (i.e. your unused type param example) and you will get an error and have to use reflection. The thing to remember, in Kotlin at least, is what the JVM signature is which is erased param types + return type and that must be unique for a common name.