Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

A public property in Kotlin is a class member, interface member, or top-level property accessible from any code that has visibility of its declaring scope. Because public is the default visibility modifier in Kotlin, explicitly declaring the public keyword is optional. By default, Kotlin implements standard public properties by generating a private backing field accompanied by public accessor methods: a getter for read-only (val) properties, and both a getter and setter for mutable (var) properties. However, this backing field generation is not universal; properties with custom accessors or those declared in interfaces do not allocate a backing field.

Syntax and Declaration

Properties are declared using the val (immutable/read-only) or var (mutable) keywords. The public modifier can be omitted entirely. When declared in an interface, a public property defines a contract for accessors but cannot maintain state.
interface Identifiable {
    // Public property contract (no backing field)
    val id: String
}

class Example : Identifiable {
    // Implicitly public (idiomatic Kotlin)
    override val id: String = "123"

    // Explicitly public
    public var explicitProperty: Int = 42
}

JVM Representation

When compiled to the JVM, standard Kotlin properties are not exposed as public fields. Instead, the compiler encapsulates the state, translating a public Kotlin property into a private JVM field with public getter and setter methods. Given the following Kotlin code:
class User {
    var name: String = "Alice"
}
The Kotlin compiler generates bytecode conceptually equivalent to this Java implementation:
public final class User {
    @NotNull
    private String name = "Alice";

    @NotNull
    public final String getName() {
        return this.name;
    }

    public final void setName(@NotNull String value) {
        this.name = value;
    }
}

The @JvmField Annotation

To bypass accessor generation and expose a property as a bare public field on the JVM, Kotlin provides the @JvmField annotation. When applied to a public property, the compiler does not generate getters or setters, and the backing field itself takes on the public visibility of the Kotlin property.
class Data {
    @JvmField
    public var rawValue: Int = 100
}

Custom Accessors

A public property can define custom logic for its accessors. The property remains public, but the retrieval or mutation logic is modified.
class Rectangle {
    var width: Int = 0
    var height: Int = 0

    // Public property with a custom getter. No backing field is generated.
    public val area: Int
        get() = width * height
}

Asymmetric Visibility

Kotlin allows the setter of a public property to have a more restrictive visibility modifier than the property itself. This keeps the read access public while restricting write access to the defining class.
class StateManager {
    // The property and its getter are public, but the setter is private
    public var currentState: String = "Idle"
        private set
}

Top-Level Public Properties

Public properties can be declared at the file level, outside of any class body. When compiled, standard top-level public properties are generated as static backing fields with static accessor methods within a synthetic facade class named after the file (e.g., FileNameKt). However, if a top-level public property is marked with the const modifier (making it a compile-time constant), Kotlin explicitly compiles it to a public static final field on the JVM and does not generate a getter method.
// Compiled to a private static field with a public static getter/setter in FileNameKt
var globalCounter: Int = 0

// Compiled directly to a public static final field in FileNameKt (no getter)
public const val MAX_TIMEOUT: Int = 5000

Backing Field Generation Rules

A public property will only generate a private backing field in memory if at least one of the following conditions is met:
  1. It uses the default implementation of at least one accessor.
  2. A custom accessor explicitly references the field identifier.
If a public property defines custom accessors that do not reference field (such as computed properties), or if it is declared in an interface, no memory is allocated for the property state.
Master Kotlin with Deep Grasping Methodology!Learn More