在 Kotlin 中使用 Java 记录类型
Records are classes in Java for storing immutable data. Records carry a fixed set of values – the records components. They have a concise syntax in Java and save you from having to write boilerplate code:
// Java
public record Person (String name, int age) {}
The compiler automatically generates a final class inherited from java.lang.Record with the following members:
- a private final field for each record component
- a public constructor with parameters for all fields
- a set of methods to implement structural equality:
equals()
,hashCode()
,toString()
- a public method for reading each record component
Records are very similar to Kotlin data classes.
Using Java records from Kotlin code
You can use record classes with components that are declared in Java the same way you would use classes with properties in Kotlin. To access the record component, just use its name like you do for Kotlin properties:
val newPerson = Person("Kotlin", 10)
val firstName = newPerson.name
Declare records in Kotlin
Kotlin supports record declaration only for data classes, and the data class must meet the requirements.
To declare a record class in Kotlin, use the @JvmRecord
annotation:
Applying
@JvmRecord
to an existing class is not a binary compatible change. It alters the naming convention of the class property accessors.
@JvmRecord
data class Person(val name: String, val age: Int)
This JVM-specific annotation enables generating:
- the record components corresponding to the class properties in the class file
- the property accessor methods named according to the Java record naming convention
The data class provides equals()
, hashCode()
, and toString()
method implementations.
Requirements
To declare a data class with the @JvmRecord
annotation, it must meet the following requirements:
- The class must be in a module that targets JVM 16 bytecode (or 15 if the
-Xjvm-enable-preview
compiler option is enabled). - The class cannot explicitly inherit any other class (including
Any
) because all JVM records implicitly inheritjava.lang.Record
. However, the class can implement interfaces. - The class cannot declare any properties with backing fields – except those initialized from the corresponding primary constructor parameters.
- The class cannot declare any mutable properties with backing fields.
- The class cannot be local.
- The primary constructor of the class must be as visible as the class itself.
Enabling JVM records
JVM records require the 16
target version or higher of the generated JVM bytecode.
To specify it explicitly, use the jvmTarget
compiler option in Gradle or Maven.
Further discussion
See this language proposal for JVM records for further technical details and discussion.