Solucionado (ver solução)
Solucionado
(ver solução)
3
respostas

Por que um casting (String) dentro do equals da classe String?

public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String)anObject;   <<<====Minha duvida
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }
class Teste{
    public static void main(String[] args) {
        String s1 = "Teste1";
        String s2 = new String("Teste1");

        if(s1 == s2){
            System.out.println("Elas são objetos iguais");
        }
        if(s1.equals(s2)){
            System.out.println("Elas batem com o mesmo conteudo");
        }
    }
}

Tenho a seguinte duvida no metodo equals() da classe String que começa no segundo "if" quando ele testa se o objeto passado é do tipo String ....if (anObject instanceof String){...}. Ou seja, eu só entro nessa condição se o objeto for do tipo String, correto? E agora que vem minha duvida! Se eu já tenho certeza que o objeto passado é de uma instância do tipo String, porque então que ao criar anotherString eu simplesmente não faço isso?

String anotherString = anObject;

Pois anObject é uma String, se não ele nem entrava nessa condição que foi verificada pelo if. Por que eu ainda tenho que usar um cast, do tipo String em algo que já é uma String? Dessa forma.

String anotherString = (String)anObject;

Por favor! O que eu não percebi que eu estou tendo esse erro de pensamento.

3 respostas

Oi Daniel,

O problema é que em tempo de compilação o método equals(Object anObject) não tem como saber que esse parâmetro do tipo Object é uma String. Pensa assim: um object pode ser um Integer ou BigDecimal? Se puder, ele não pode deixar vc atribuir a uma String. A não ser que você confie que, em tempo de execução esse objeto realmente vai ser uma String.

Eu entendi! Porem eu achava que mesmo em tempo de compilação o método sem saber que objeto foi passado, eu não correria esse risco justamente por conta do "anObject instanceof String" Se eu criar aqui um exemplo copiando essa parte do código e fazendo uma pequena alteração no código tirando esse casting, ainda assim ira funcionar "sempre"? Pois mesmo o método não sabendo qual tipo de objeto foi passado, em tempo de execução quando chegar na verificação instanceof ele vai verificar e ter certeza que é um tipo String, mas isso em tempo de execução. Esta correto isso? Mesmo sem o casting esse código em tempo de execução nunca irá ter um erro em execução, por em tempo de compilação ele não ter como saber que método eu irei passar na execução?

solução!

O que vc fala faz bastante sentido, tem até uma linguagem, chamada Kotlin, que implementa isso. Caso passe pelo instanceof ele te libera do casting... Mas no Java não vai rolar :(.