Java – instanceof Pattern Matching

O Pattern Matching para o operador instanceof foi introduzido como um recurso de visualização com JDK 14 e foi finalizada com JDK 16, desde então, não é surpreendente ver mudanças sendo feitas no JDK para tirar vantagem dessa nova funcionalidade.

Nesta postagem, vamos focar no uso de Pattern Matching do instanceof na implementação anterior (antes da JDK 14) e atual.

Anterior:

if (animal instanceof Duck) {
    Duck duck = (Duck) animal;
    duck.quack();
} else if (animal instanceof Cat) {
    Cat cat = (Cat) animal;
    cat.meow();
}

Atual:

if (animal instanceof Duck duck) {
    duck.quack();
} else if (animal instanceof Cat cat) {
    cat.meow();
}

O que está a acontecer? Simplesmente o resultado do instanceof está sendo atribuído via pattern matching às variáveis cat e duck.

Mais um exemplo bem didático:

if (object instanceof String str && str.length() > 1) {
    //do something...
} else if (object instanceof List list) {
    list.forEach(o -> {
        if (o instanceof String str && str.length() > 1) {
            //do something...
        }
    });
}

Muito legal, não é? Com essa abordagem a nova feature faz com que tenhamos algumas boas vantagens, pois já não será mais preciso escrever tanto código, que dependendo do negócio se tornava muito estressante e tedioso.

Algumas vantagens:

  • Não é mais preciso escrever este tipo de código em que precisamos testar o tipo e fazer uma conversão para cada bloco condicional;
  • Não é mais preciso repetir o nome do tipo três vezes para cada bloco condicional;
  • A legibilidade é muito limpa, pois já não sujamos a conversão e extração do valor para a variável;
  • Não existe mais problemas com legibilidade, e previne possíveis erros de excecução ao adicionar várias variáveis e casts, ou adicionando um novo tipo à da super classe. (ex: animal)

Essa feature veio para tornar nosso código conciso, mais simples de escrever e fácil de ler, todos os dias.

Essas mudanças no JDK para alavancar o pattern matching de instância podem fornecem muitas idéias e exemplos para os desenvolvedores saberem onde começar a aplicar isso no próprio código.

Brian Goetz usa um bom exemplo de como muitas vezes implementamos equals (Object), e vamos exemplificá-lo aqui com o objeto chamado “Marreta“:

É uma implementação bastante comum e conhecida, não é?

@Override
public boolean equals(Object obj){
    if (obj instanceof Marreta) {
       Marreta other = (Marreta) obj;
        if (model.equals(other.model) && strength == other.strength) {
            return true;
        }
    }
    return false;
}

Agora utilizando o Pattern Matching do instanceof:

@Override
public boolean equals(Object obj){
    return (obj instanceof Marreta other && 
            model.equals(other.model) && 
            strength == other.strength);
}

Bom, como desenvolvedores, costumamos usar o operador instanceof em nosso código, e minha intenção foi apresentar e exemplificar como utiliza-lo atualmente(desde a JDK 14), de forma a melhorar sua produtividade e legibilidade.

Obrigado.

🙂

Published by Ivan Marrêta

Software Engineer

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: