Reputation: 3227
I'm interested to know how kotlin.String
is implemented, since it reports itself as a java.lang.String
, yet has more methods available (according to ki
autocompletion) even accounting for extension methods:
[34] kotlin.String().javaClass
res17: Class<String> = class java.lang.String
[35] "10".javaClass
res18: Class<String> = class java.lang.String
[36] "10".toLong()
res19: Long = 10
[37] java.lang.String("10").javaClass
res20: Class<String> = class java.lang.String
[38] java.lang.String("10").toLong()
ERROR Unresolved reference. None of the following candidates is
applicable because of receiver type mismatch:
public inline fun String.toLong(): Long defined in kotlin.text
public inline fun String.toLong(radix: Int): Long defined in
kotlin.text (Line_39.kts:1:24)
Is kotlin.String
really a java.lang.String
?
Upvotes: 1
Views: 917
Reputation: 3227
To expand on the other comments posted here, it looks like kotlin.String
is not a java.lang.String
, but it does compile to one, according to the java/kotlin type mapping. So even though the runtime class is the same, the compiler treats them differently. Since the toLong
extension method is implemented on kotlin.String, it is not available for java.lang.String
.
You can pull the same trick in reverse:
[71] fun java.lang.String.zero(): Long = 0
[72] java.lang.String().zero()
res36: Long = 0
but this extension method is not available for a kotlin.String
, even though it compiles to a java.lang.String
.
[73] "kotlin string".javaClass
res37: Class<String> = class java.lang.String
[74] "kotlin string".zero()
ERROR Unresolved reference. None of the following candidates is applicable because of receiver type mismatch:
public final fun String.zero(): Long defined in Line_72 (Line_75.kts:1:17)
To further complicate the matter, a java.lang.String
is normally loaded as a kotlin.String
unless you give the fully qualified name.
[0] java.lang.String("12345").toLong()
ERROR Unresolved reference. None of the following candidates is applicable because of receiver type mismatch:
public inline fun String.toLong(): Long defined in kotlin.text
public inline fun String.toLong(radix: Int): Long defined in kotlin.text (Line_1.kts:1:27)
[1] java.lang.String("12345").substring(0).toLong()
res0: Long = 12345
So the answer is no, a kotlin.String
is not a java.lang.String
. They are interoperable because they compile to the same class, but the compiler still distinguishes between them.
Related question: does Any == Object
Upvotes: 1
Reputation: 1120
Kotlin supports adding functionality to classes without extending the class, via extensions: https://kotlinlang.org/docs/extensions.html
You can see String.toLong is added along with many other extensions to base Java classes via the kotlin.text package here: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/
Upvotes: 3