PC パソコン

Causes and Solutions for Kotlin “Conflicting overloads”

“`html

When writing code in Kotlin, you may encounter an error called “Conflicting overloads”.

This error occurs when multiple functions, constructors, or other elements with the same name are defined and the Kotlin compiler cannot distinguish between them.

Kotlin supports overloading, which allows functions with the same name to be defined when their argument types or numbers differ, but an error occurs when definitions that are effectively treated as having the same signature are duplicated.

This article introduces the main causes of the “Conflicting overloads” error in Kotlin and the basic ways to resolve it.

What Is “Conflicting overloads”?

“Conflicting overloads” is an error indicating that multiple overloads conflict with each other and the compiler cannot treat them as separate definitions.

For example, if you define two functions with the same name and arguments of the same type, they conflict because both have the same calling pattern.

fun show(value: Int) {
    println("A: $value")
}

fun show(value: Int) {
    println("B: $value")
}

In this case, both show() functions are treated as the same function that accepts one Int, so “Conflicting overloads” is displayed.

Cause 1: Defining Duplicate Functions with the Same Signature

The most basic cause is defining multiple functions with the same name and the same argument types.

fun calculate(value: Int) {
    println(value)
}

fun calculate(value: Int) {
    println(value * 2)
}

These two calculate() functions cannot be distinguished because both accept one Int.

If they are needed for different operations, change the function name.

fun calculate(value: Int) {
    println(value)
}

fun calculateDouble(value: Int) {
    println(value * 2)
}

Also, if you want to overload functions with the same name, you need to change the types or number of arguments.

fun calculate(value: Int) {
    println(value)
}

fun calculate(value: Double) {
    println(value)
}

Cause 2: Overloading by Changing Only the Argument Names

In Kotlin, even if the argument names are different, functions are not treated as separate overloads if the argument types and number of arguments are the same.

fun printValue(number: Int) {
    println(number)
}

fun printValue(value: Int) {
    println(value)
}

In this example, the argument names are different, number and value, but both functions accept one Int.

Therefore, from the compiler’s perspective, they are functions with the same signature and conflict with each other.

To distinguish overloads, there must be differences in the argument types, number of arguments, or similar characteristics rather than just the argument names.

Cause 3: Defining Functions That Differ Only in Return Type

Changing only the return type does not allow Kotlin to distinguish between overloads.

fun getValue(): Int {
    return 10
}

fun getValue(): String {
    return "10"
}

In this case, both are getValue() functions with no arguments, so they have the same calling pattern.

Because they cannot be distinguished by return type alone, “Conflicting overloads” occurs.

If they are needed for different operations, change the function names.

fun getIntValue(): Int {
    return 10
}

fun getStringValue(): String {
    return "10"
}

Cause 4: Calling Patterns Conflict Due to Default Arguments

When default arguments are used, even if the definitions themselves are different, the same calling pattern may become valid and cause a conflict.

fun show(value: Int) {
    println(value)
}

fun show(value: Int, message: String = "Hello") {
    println("$message: $value")
}

With definitions like these, the candidates may overlap depending on how the functions are called.

When using default arguments, it is important to check whether the calling patterns overlap with existing overloads.

Cause 5: Constructors Conflict Within the Same Class

Not only functions but also constructors conflict when multiple definitions have the same argument structure.

class User {

    constructor(name: String) {
        println(name)
    }

    constructor(value: String) {
        println(value)
    }
}

Although the argument names are different, both constructors accept one String.

Therefore, the compiler cannot distinguish between them.

If you provide multiple constructors, you need to change the argument types or number of arguments.

class User {

    constructor(name: String) {
        println(name)
    }

    constructor(id: Int) {
        println(id)
    }
}

Cause 6: Identical Functions Exist in the Same File or Package

“Conflicting overloads” may occur not only when identical functions exist in the same file, but also when the same top-level function is defined in another file within the same package.

// FileA.kt
fun display(value: String) {
    println(value)
}

// FileB.kt
fun display(value: String) {
    println(value)
}

If they are in the same package, these are treated as top-level functions existing in the same namespace.

Therefore, you need to check not only the file where the error occurs but also whether another file in the same package contains a function with the same name and signature.

Cause 7: Copied Code Is Duplicated

The error may also be caused by copying function or class code and leaving the old definition without deleting it.

In particular, when editing a large file or moving processing to another file, check whether multiple copies of the same function remain.

If “Conflicting overloads” suddenly appears, checking whether a function that was recently copied, moved, or refactored has been duplicated can make it easier to identify the cause.

Cause 8: Extension Function Definitions Conflict

Extension functions can also conflict if functions with the same name and the same argument structure are defined for the same type within the same scope.

fun String.show() {
    println(this)
}

fun String.show() {
    println("Value: $this")
}

Because both are show() functions with no arguments for String, they conflict as the same extension function.

If the operations need to be separated, change the function names or argument structures.

Cause 9: Generics Result in Effectively Identical Definitions

When using generics, depending on how they are defined, functions may also conflict from the compiler’s perspective.

fun <T> process(value: T) {
    println(value)
}

fun <R> process(value: R) {
    println(value)
}

Even though the type parameter names are different, T and R, both functions have the same structure and accept one value of any type.

Therefore, simply changing the type parameter name does not make them separate overloads.

Difference Between Conflicting overloads and Overload resolution ambiguity

“Conflicting overloads” and “Overload resolution ambiguity” are similar, but they occur in different situations.

“Conflicting overloads” occurs when the definitions themselves cannot be distinguished and conflict at the point where functions or other elements are defined.

On the other hand, “Overload resolution ambiguity” occurs when multiple valid candidates exist and it is impossible to determine which candidate should be used at the point where a function is called.

When “Conflicting overloads” is displayed, the basic approach is to first check whether the definitions of functions, constructors, or other elements themselves are duplicated rather than checking how the functions are called.

Resolve the Error by Changing the Function Name

If different operations need to be performed with the same argument structure, separating the function names is the clearest solution.

fun saveText(value: String) {
    println(value)
}

fun printText(value: String) {
    println(value)
}

By naming functions according to the purpose of the operation, you can not only avoid conflicts but also make the meaning of the code easier to understand.

Resolve the Error by Changing the Argument Types or Number of Arguments

If functions need to be overloaded with the same name, give them different argument types or numbers of arguments.

fun show(value: String) {
    println(value)
}

fun show(value: Int) {
    println(value)
}

fun show(value: String, count: Int) {
    repeat(count) {
        println(value)
    }
}

When the argument types or numbers differ in this way, each function can be distinguished as a separate overload.

Points to Check When “Conflicting overloads” Appears

When “Conflicting overloads” appears, check whether a definition with the same signature exists for the function or constructor causing the error.

  • Have you defined multiple functions with the same name and the same argument types?
  • Have you created functions that differ only in their argument names?
  • Are you overloading functions by changing only the return type?
  • Do default arguments cause calling patterns to overlap?
  • Have you defined multiple constructors with the same argument structure?
  • Is there an identical top-level function in another file within the same package?
  • Does an old function remain because of copying or refactoring?
  • Have you defined the same extension function more than once?
  • Are there functions with the same structure that differ only in their generic type parameter names?

Rather than looking only at the function shown at the error location, searching for the same function name throughout the project makes it easier to find duplicate definitions.

Summary

Kotlin’s “Conflicting overloads” is an error that appears when multiple functions, constructors, or other elements with the same name are defined and the compiler cannot distinguish them as separate definitions.

Typical causes include duplicate functions with the same signature, definitions that differ only in argument names, functions that differ only in return type, constructors with the same structure, and duplicate top-level functions or extension functions.

Basically, the error can be resolved by removing unnecessary duplicate definitions, changing function names, or changing the types or number of arguments.

Also, if the error suddenly appears, it is important to check whether multiple copies of the same function remain as a result of copying, moving, or refactoring code.

When “Conflicting overloads” appears, focus on the definition side rather than the call side and check whether “the compiler can clearly distinguish each function.” This makes it easier to identify the cause.

“`