Why is this an issue?

If a local variable is never reassigned, it should be declared val to make it a constant within its scope. This makes the code easier to read and protects the variable from accidental re-assignments in future code changes.

What is the potential impact?

Readability and Understanding

If a variable is declared val, it is evident to readers that the variable value is never altered but serves as a constant. This makes it easier to understand the code because readers do not need to keep track of possible state changes of the variable.

Wrong code

Developers might intend for a variable to remain unchanged and have their code relying on that constraint. For example, a variable could be expected to have a specific range. Changing the value of the variable could break that constraint. Also, developers could have assigned the wrong variable. If the developers inject a value into a variable with an annotation, they should declare it as late initialized.

Declare variables that remain unchanged as val to avoid these mistakes.

How to fix it

Replace the keyword var with val.

Code examples

Noncompliant code example

fun resize(): Int {
    var newLength = max(16, 2*bufferLength) // Noncompliant, `newLength` is assigned only once
    allocBuffer(newLength)
    return resize
}

class MyClass {
    @inject
    private var myVar: Int = 0 // Noncompliant, `myVar` is late initialized and should be declared as such
}

Compliant solution

fun resize(): Int {
    val newLength = max(16, 2*bufferLength) // Compliant
    allocBuffer(newLength)
    return resize
}

class MyClass {
    @inject
    private lateinit var myVar: Int // Compliant
}

Resources

Documentation

Articles & blog posts