assertEquals
usa o equals
método para comparação. Há uma afirmação diferente assertSame
, que usa o ==
operador.
Para entender por ==
que não deve ser usado com strings, você precisa entender o que ==
faz: faz uma verificação de identidade. Ou seja, a == b
verifica se a
e se b
refere ao mesmo objeto . Ele está embutido no idioma e seu comportamento não pode ser alterado por diferentes classes. O equals
método, por outro lado, pode ser substituído por classes. Embora seu comportamento padrão (na Object
classe) seja fazer uma verificação de identidade usando o ==
operador, muitas classes, inclusive String
, substituem-na para fazer uma verificação de "equivalência". No caso de String
, em vez de verificar se a
e se b
referir ao mesmo objeto,a.equals(b)
verifica se os objetos a que se referem são as duas cadeias que contêm exatamente os mesmos caracteres.
Tempo da analogia: imagine que cada String
objeto seja um pedaço de papel com algo escrito nele. Digamos que eu tenha dois pedaços de papel com "Foo" escrito neles e outro com "Bar" escrito. Se eu pegar os dois primeiros pedaços de papel e utilizá ==
-los para compará-los, ele retornará false
porque está essencialmente perguntando "estes são o mesmo pedaço de papel?". Nem precisa olhar para o que está escrito no papel. O fato de eu estar entregando dois pedaços de papel (em vez do mesmo duas vezes) significa que ele retornará false
. Se eu usar equals
, no entanto, o equals
método lerá os dois pedaços de papel e verá que eles dizem a mesma coisa ("Foo"), e assim retornará true
.
O pouco que se confunde com Strings é que o Java tem um conceito de "internar" Strings, e isso é (efetivamente) executado automaticamente em qualquer literal de string em seu código. Isso significa que, se você tiver dois literais de string equivalentes em seu código (mesmo que estejam em classes diferentes), eles na verdade se referem ao mesmo String
objeto. Isso faz com que o ==
operador retorne com true
mais frequência do que se poderia esperar.