Why is this an issue?

In Kotlin, nullability is a part of the type system. By default, any given type T is non-nullable. If you append a "?" to the type, it becomes nullable: T?.

When accessing properties or functions of a nullable type, you need to handle the case when the target is null. However, while accessing a non-nullable type, it is redundant to test for null, as the compiler statically ensures that the value can never be null. So all the nullability checks on the non-nullable types are considered code smells.

On the other hand, performing a null-check on a value that is always null is equally as redundant.

Here is an example of a non-nullable variable. s is of a type String and cannot be null.

val s: String = ""

Here is an example of a nullable variable. Nullable variables are declared by using the ?.

val s: String? = null

Explicit null checks are comparing a result to null using == or != operators. In Kotlin, there are various other means of implicitly or explicitly performing a null check or assertion, including the following:

How to fix it

Avoid using null checks on non-nullable variables and values that are always null.

Code examples

If your variable type is non-nullable, any null checks are redundant. For example, if (s == null) {}, requireNotNull(s) and checkNotNull(s) can be dropped from your code.

Noncompliant code example

val s: String = ""
if (s != null) { doSomething() } // This statement is always true

Compliant solution

val s: String = ""
doSomething()

Noncompliant code example

fun foo(s: String) {
  if (s == null) { // Noncompliant, `s == null` is always false.
      doSomething()
  }
}

Compliant solution

fun foo(s: String) {
  doSomething()
}

Noncompliant code example

fun foo(s: String): String {
    return s ?: "" // Noncompliant, ?: is useless and the empty string will never be returned.
}

Compliant solution

fun foo(s: String): String {
    return s
}

If s is nullable, the elvis operation makes sense:

fun foo(s: String?): String {
    return s ?: ""
}

Noncompliant code example

fun foo(s: String) {
    s!!.doSomething() // Noncompliant, `s` can never be null.
}

Compliant solution

fun foo(s: String) {
    s.doSomething()
}

Resources

Documentation

Articles & blog posts