Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

277
Visualizações
Why isn't Kotlin complaining about ambiguity? And why is it calling the secondary constructor?

I was testing something in Kotlin and now I won't be able to sleep properly if I don't find an answer.

Look at this class:

data class Person(
    val name: String,
    val age: Int? = 0
) {
    constructor(
        secondName: String,
        secondAge: Int = 5
    ) : this(
        name = "$secondName 2",
        age = secondAge
    )
}

fun main() {
    val firstCase  = Person("Lorem")     // Complaints about ambiguity.
    val secondCase = Person("Lorem", 42) // Calls secondary constructor.
}

Complaining about ambiguity in the firstCase is understandable, but why it is not happening the same in the secondCase? And why did it decide to call the secondary constructor and not the main constructor?

Now if I add another parameter on the main constructor with a default value:

data class Person(
    val name: String,
    val age: Int? = 0,
    val isAdult: Boolean = false
) {
    constructor(
        secondName: String,
        secondAge: Int = 5
    ) : this(
        name = "$secondName 2",
        age = secondAge
    )
}

fun main() {
    val thirdCase = Person("Lorem") // Calls secondary constructor.
}

I was expecting to have ambiguity for the thirdCase, just like in the firstCase. But no! It calls the secondary constructor. Why?!

over 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

The rules of method resolution in Kotlin (and in Java) can be a bit arcane. Thankfully, they do the obvious thing in nearly all situations — which is clearly the point! — but there are a few surprising corner cases.

The general principle is that it picks the most specific method that could match, and only gives an error if there isn't a single winner.

So in your second case, the arguments are String and Int. The candidates are the primary constructor (taking String and Int?), and the secondary constructor (taking String and Int). The latter is a more specific match, because Int is a subtype of Int?, and so it picks that one.

But in your first case, the only argument provided is a String, which matches both constructors equally, so there's no clear winner, and it flags up the ambiguity.

Your third case is even less obvious. However, the section of the Kotlin spec that discusses how to choose the most specific candidate from all the overloads says:

For each candidate we count the number of default parameters not specified in the call (i.e., the number of parameters for which we use the default value). The candidate with the least number of non-specified default parameters is a more specific candidate

I think that's what's happening in your third case: it picks the secondary constructor (which would leave only one parameter with its default value) over the primary (which would leave two).

over 4 years ago · Santiago Trujillo Relatório

0

Kotlin gives more priority to a function that is more specific. Consider this example:

foo(dog) // invokes foo(Dog)

fun foo(animal: Animal) {}
fun foo(dog: Dog) {}

In this case foo(dog) is also ambiguous, but in fact, it uses foo(Dog) function. To use the other one, we have to explicitly upcast:

foo(dog as Animal)

Because Int is a subtype of Int?, your secondary constructor is more specific than the primary constructor and this is why it is preferred.

over 4 years ago · Santiago Trujillo Relatório

0

In your first example, there is no ambiguity when you use two arguments, because it selects the constructor with the most specific type matching your parameter. There is no ambiguity to choose between the one with Int and the one with Int? because Int is more specific than Int?.

When you provide a single argument, it is ambiguous since you are not providing any argument that can help distinguish whether you want Int or Int?.

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda