> ## 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.

# Kotlin Custom Setter

A custom setter in Kotlin is an explicit implementation of the `set` accessor for a mutable (`var`) property, allowing developers to intercept and define the exact execution logic that occurs during property assignment. By default, Kotlin generates implicit getters and setters for properties, but defining a custom setter overrides the default assignment mechanism.

## Syntax

The custom setter is declared immediately following the property declaration using the `set` keyword. It takes a single parameter representing the incoming value.

```kotlin theme={"dark"}
var greeting: String = "Hello"
    set(value) {
        // Custom execution logic
        field = value
    }
```

## The Backing Field (`field`)

To store a value in memory, Kotlin provides an implicit backing field accessed via the `field` identifier. Inside the custom setter, the incoming value must be assigned to `field` rather than the property name itself. Assigning directly to the property name within its own setter triggers a recursive invocation of the setter, resulting in a `StackOverflowError`.

```kotlin theme={"dark"}
var data: String = "Initial"
    set(value) {
        // CORRECT: Assigns to the implicit backing field
        field = value 
        
        // INCORRECT: Causes infinite recursion
        // data = value 
    }
```

*Note: A property in Kotlin has a backing field if it uses the default implementation of at least one of the accessors, or if a custom accessor references it through the `field` identifier. If a custom setter does not reference `field`, the property will still have a backing field unless a custom getter is also explicitly defined and also does not reference `field`. Omitting the getter entirely generates a default getter that implicitly requires a backing field. A critical language rule dictates that a property without a backing field **cannot have an initializer**.*

## Parameter Naming and Type

By convention, the setter parameter is named `value`, but it can be arbitrarily renamed. The parameter's type is inferred from the property declaration. While optional, the type can be explicitly declared in the setter signature, provided it exactly matches the property's declared type.

```kotlin theme={"dark"}
var count: Int = 0
    set(newValue: Int) { // Parameter renamed and type explicitly declared
        field = newValue
    }
```

## Visibility Modifiers and Annotations

The visibility of a custom setter can be modified independently of the property, provided the setter's visibility is equal to or more restrictive than the property's visibility. Annotations can also be applied directly to the `set` keyword.

```kotlin theme={"dark"}
var internalState: String = "Default"
    private set(value) {
        field = value
    }
```

If only the visibility or annotations need to be changed without altering the default assignment logic, the setter body can be omitted entirely. Built-in annotations (like `@Suppress`) or properly imported external annotations can be applied directly to the modifier:

```kotlin theme={"dark"}
var restrictedProperty: Int = 0
    @Suppress("unused") private set
```

<div
  style={{ 
display: "flex", 
justifyContent: "space-between", 
alignItems: "center", 
maxWidth: "754px", 
padding: "1rem 0",
marginBottom: "24px"
}}
>
  <span style={{ fontWeight: "bold", fontSize: "1.25rem", color: "var(--tw-prose-headings)", fontFamily: "Inter, ui-sans-serif, system-ui, sans-serif" }}>Tired of Poor Kotlin Skills? Fix That With Deep Grasping!</span>

  <a
    href="https://syntblaze.com"
    target="_blank"
    style={{ 
  marginLeft: "24px",
  textDecoration: "none", 
  backgroundColor: "#007AFF",
  color: "#ffffff", 
  padding: "6px 16px", 
  borderRadius: "16px",
  fontSize: "0.9rem",
  fontWeight: "600",
  textAlign: "center",
  transition: "background-color 0.2s ease"
}}
  >
    Learn More
  </a>
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/skill-tracking.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=b9b0305c93bb501c9e767b5c76c88835" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/skill-tracking.png" />

  <img src="https://mintcdn.com/syntblazellc/23tyuOzaWS88qFlc/images/nuggets.png?fit=max&auto=format&n=23tyuOzaWS88qFlc&q=85&s=c86c80197299762989e9b882419b2109" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/nuggets.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/bite-sized-exercises.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=a65f9a38c37ff28ab73ed783c53c60e3" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/bite-sized-exercises.png" />
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap", marginTop: "12px" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/mastery-chain.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=748a1763454713e679260fbb95f154a2" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/mastery-chain.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-previews.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=242f61448ff5dd6deaaab2dccc13b507" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-previews.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-explanations.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=cf0fc1c31f9cd0fc26716781be05fbc9" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-explanations.png" />
</div>
