11
votes

In Kotlin, suppose, I have class:

class MyKotlinClass {
    lateinit var field: String
}

According to docs:

Late-Initialized properties are also exposed as fields. The visibility of the field will be the same as the visibility of lateinit property setter.

I can use in java code either myKotlinClass.field or myKotlinClass.getField(). I want to disable field access and remain only access through getter and setter.

How can I achieve this and remain lateinit modifier?

3

3 Answers

13
votes

You can use @JvmSynthetic that hides declarations from Java (and not from Kotlin). Just annotate the backing field of the property:

@field:JvmSynthetic
lateinit var field: String

Though the field will remain public in the bytecode, it will also have the synthetic modifier, which prevents it from being used in Java sources. However, the field seems to be still accessible through reflection at runtime.

See also: another question about @JvmSynthetic (though no definite answer there).

2
votes

The classical solution to this problem would be to use property delegation:

import kotlin.properties.Delegates

class MyKotlinClass {
    var field: String by Delegates.notNull()
}

This code does exactly what you asked for in the question

1
votes

The visibility of lateinit field is derived from the visibility of setter of the corresponding property, so another option is to have a property with non-public setter:

lateinit var field: String
    private set

The drawback of this approach is that the setter itself becomes inaccessible outside of the class.