fun main() {
print(test(1, "abc", 4))
}
fun <T> test(criteria: T, actual: T, points: Int): Int {
if (criteria == null) return 0
return if (criteria == actual) points else 0
}
// prints 0
The arguments provided in main function does not match generics contract in the test function since the first argument and the second argument should be of the same type. How does this compile? Tested with Kotlin 1.7.10, here's the kotlin playground link: https://pl.kotl.in/s9fJVUw0D
CodePudding user response:
When you look at the Bytecode of your test function, you will immediately notice the limitation(?) of the JVM when it comes to "generics".
// declaration: int test<T>(T, T, int)
public final static test(Ljava/lang/Object;Ljava/lang/Object;I)I
In other words, Java has this thing called type erasure which is a pain when you come from other generic-supporting languages.
What you maybe want, if you want the code to fail is to play with the Covariance/Invariance rules...
so perhaps:
fun <T: Int?> test2(criteria: T, actual: T, points: Int): Int {
if (criteria == null) return 1
return if (criteria == actual) points else 0
}
Will work for integers.
print(test2(1, 2, 4))
will print 0
print(test2(1, 1, 4))
Will print 4
print(test2(1, "2", 4))
Will fail.