Why is this an issue?
An interface that declares only a single function should be marked as function interface. Function interfaces can be instantiated from lambda
expressions directly and are, therefore, more comfortable to use.
Also, consider using a function type instead of a function interface. In many situations, a function type is sufficient. A function interface is
only required when the function must not be anonymous or when an object should implement multiple function interfaces at once.
What is the potential impact?
Complexity
When an interface is declared functional, SAM conversion is enabled. This means that any lambda expression that matches the interface’s
single function’s signature can be converted into an instance of the interface, without the need for an explicit class or singleton object to
implement the interface.
Wrong logic
An interface can still be marked @FunctionalInterface
in Kotlin, but this has no effect, and SAM conversion will not work. The
annotation java.lang.FunctionalInterface
is only a Java platform type with no special meaning in Kotlin.
How to fix it
Replace interface
with fun interface
. If the interface is annotated with @FunctionalInterface
, remove the
annotation.
Code examples
Noncompliant code example
interface IntMapper<T> { // Noncompliant
fun map(value: Int): T
}
interface StringMapper<T> { // Noncompliant
fun map(value: String): T
}
@FunctionalInterface // Noncompliant
interface ProgressCallback {
fun progressChanged(percent: Double)
}
Compliant solution
fun interface IntMapper<T> { // Compliant, function interface used
fun map(value: Int): T
}
typealias StringMapper<T> = (value: String) -> T // Compliant, functional type used
fun interface ProgressCallback { // Compliant, function interface used
fun progressChanged(percent: Double)
}
Resources
Documentation
Articles & blog posts