1

Kotlin defines its own String class:

public class String : Comparable<String>, CharSequence {
    companion object {}        
    public operator fun plus(other: Any?): String    
    public override val length: Int    
    public override fun get(index: Int): Char    
    public override fun subSequence(startIndex: Int, endIndex: Int): CharSequence    
    public override fun compareTo(other: String): Int
}

The instances of this class are constructed via inline functions defined in StringsJVM.kt:

public inline fun String(bytes: ByteArray, offset: Int, length: Int): String =
    java.lang.String(bytes, offset, length, Charsets.UTF_8) as String

Questions:

  1. How does the cast of java.lang.String to kotlin.String work? It is not a subtype but a separate implementation of CharSequence
  2. Member length is a val with no value assigned. How does this compile? It would need to be a lateinit var

I presume there must some sort of code pre-processing going on before the compilation.

Please feel free to edit this question with a more apt title.

Kshitiz Sharma
  • 17,947
  • 26
  • 98
  • 169

1 Answers1

2

Basically, kotlin.String is a mapped type, which means that, when compiled into the JVM bytecode, all Kotlin usages of the kotlin.String type are translated to equivalent usages of java.lang.String.

This technique ensures compatibility of the Kotlin and Java types and at the same time allows adding Kotlin-idiomatic API to the Java types.

You can inspect the *.class files produced by the compiler and see that they mention the java.lang.String.

See also: a sililar Q&A.


As to the compilation of the length property of the kotlin.String definition, you can see that it is actually never compiled but only serialized into the Kotlin builtins metadata, according to the Gradle build script of the corresponding module.

hotkey
  • 140,743
  • 39
  • 371
  • 326