Skip to main content
Operators in Kotlin are special symbols or keywords that perform specific operations on one or more operands. Architecturally, Kotlin implements most operators as syntactic sugar for standard method calls on objects. This mechanism is governed by the operator modifier, which allows classes to define or overload operator behavior by providing specifically named member or extension functions.

Operator Overloading Mechanism

When the compiler encounters an operator, it resolves it to a corresponding function call. For example, the expression a + b is translated to a.plus(b). To enable this for custom types, the function must be prefixed with the operator keyword.
class Vector(val x: Int, val y: Int) {
    operator fun plus(other: Vector): Vector {
        return Vector(this.x + other.x, this.y + other.y)
    }
}

Operator Categories and Function Mapping

Unary Prefix Operators

These operate on a single operand and are evaluated before the expression.
ExpressionTranslated Method Call
+aa.unaryPlus()
-aa.unaryMinus()
!aa.not()

Increments and Decrements

These operators mutate the operand. The compiler handles the assignment automatically; the overloaded function must return the new value, not mutate the object in place.
ExpressionTranslated Method Call
a++ / ++aa.inc()
a-- / --aa.dec()
Note: Prefix forms (++a) return the updated value. Postfix forms (a++) store the initial value, perform the inc() operation, assign the result to a, and return the stored initial value.

Arithmetic Operators

Binary operators that perform standard mathematical computations.
ExpressionTranslated Method Call
a + ba.plus(b)
a - ba.minus(b)
a * ba.times(b)
a / ba.div(b)
a % ba.rem(b)

Augmented Assignments

These combine an arithmetic operation with assignment. The compiler resolves expressions like a += b based on the availability of specific assignment functions (e.g., plusAssign) versus standard arithmetic functions (e.g., plus).
  • If plusAssign is defined, it translates to a.plusAssign(b).
  • If plusAssign is not defined, but plus is defined and a is a mutable variable (var), it translates to a = a.plus(b).
  • If both are defined and a is mutable, the compiler reports an Assignment operators ambiguity error to prevent unpredictable mutation behavior. | Expression | Translated Method Call (if specific assignment exists) | | :--- | :--- | | a += b | a.plusAssign(b) | | a -= b | a.minusAssign(b) | | a *= b | a.timesAssign(b) | | a /= b | a.divAssign(b) | | a %= b | a.remAssign(b) |

Range Operators

These operators create ranges or progressions between two values.
ExpressionTranslated Method Call
a..ba.rangeTo(b)
a..<ba.rangeUntil(b)

Equality and Inequality

Kotlin distinguishes between structural equality (==) and referential equality (===). Structural Equality: Translated to the equals() function. The compiler injects null-safety checks during translation.
ExpressionTranslated Method Call
a == ba?.equals(b) ?: (b === null)
a != b!(a?.equals(b) ?: (b === null))
Referential Equality: Evaluates whether two references point to the exact same memory address. These operators (=== and !==) are intrinsic to the JVM/runtime and cannot be overloaded.

Comparison Operators

Translated to the compareTo method, which must return an Int adhering to the standard contract (negative if less, zero if equal, positive if greater).
ExpressionTranslated Method Call
a > ba.compareTo(b) > 0
a < ba.compareTo(b) < 0
a >= ba.compareTo(b) >= 0
a <= ba.compareTo(b) <= 0

Collection and Access Operators

Kotlin provides operators for membership checking and indexed access.
ExpressionTranslated Method Call
a in bb.contains(a)
a !in b!b.contains(a)
a[i]a.get(i)
a[i, j]a.get(i, j)
a[i] = ba.set(i, b)

Invoke Operator

Parentheses translate to the invoke function, allowing instances to be called as if they were functions.
ExpressionTranslated Method Call
a()a.invoke()
a(i)a.invoke(i)

Destructuring Declaration Operators

Kotlin allows unpacking an object into multiple variables. This syntax is powered by sequentially numbered component functions.
ExpressionTranslated Method Call
val (x, y) = aval x = a.component1()
val y = a.component2()

Iterator Operator

For an object to be iterable within a for loop, it must provide an iterator operator function. The returned iterator object must subsequently provide next() and hasNext() operator functions.
ExpressionTranslated Method Call
for (item in a)val it = a.iterator()
while (it.hasNext()) { val item = it.next() }

Property Delegation Operators

The by keyword delegates the getter (and setter) of a property to another object. The delegate object must provide getValue and, for mutable properties, setValue operator functions. An optional provideDelegate operator can also be defined to intercept the delegation creation.
ExpressionTranslated Method Call
val p by dd.getValue(thisRef, property)
var p by d
p = value
d.getValue(thisRef, property)
d.setValue(thisRef, property, value)

Bitwise Operations

Unlike C-style languages, Kotlin does not use symbolic operators (like &, |, <<) for bitwise operations. Instead, it utilizes named functions combined with the infix modifier, allowing them to be called without dot notation or parentheses.
val leftShift = 1 shl 2
val bitwiseAnd = 0x0F and 0xF0
Standard bitwise functions include: shl (signed shift left), shr (signed shift right), ushr (unsigned shift right), and, or, xor, and inv (bitwise inversion, called as a standard method).
Tired of Poor Kotlin Skills? Fix That With Deep Grasping!Learn More