Importante

Você está vendo a versão anterior da nova experiência da Alura que estamos preparando para você. Em breve, ela ganha uma identidade visual novinha totalmente pensada em potencializar seus estudos!

1
resposta

[Dúvida] Dúvida sobre Gson

import com.google.gson.Gson;

record Editora(String nome, String cidade) {}
record Livro(String titulo, String autor, Editora editora) {}

public class ConversaoJsonAninhadoParaObjeto {

    public static void main(String[] args) {
        String jsonLivro = "{\"titulo\":\"Aventuras do Java\",\"autor\":\"Akemi\",\"editora\":{\"nome\":\"TechBooks\",\"cidade\":\"São Paulo\"}}";

        Gson gson = new Gson();
        Livro livro = gson.fromJson(jsonLivro, Livro.class);

        System.out.println("Objeto Livro: " + livro);
    }
}

Nesse bloco de código eu fiquei com uma dúvida, eu queria entender como o Gson conseguiu converter sem problemas a classe aninhada? Nesse caso a classe Editora seria considerada uma classe static?

1 resposta

Olá Eduardo.
Tudo bem?
Ótima pergunta.
Na verdade, o Gson não precisa que a classe seja static para conseguir realizar a desserialização nesse exemplo.
O que acontece é que o Gson utiliza reflexão (Reflection API) para analisar a estrutura da classe Livro.
Quando ele encontra o atributo:

Editora editora

e no JSON existe:

"editora": {
  "nome": "TechBooks",
  "cidade": "São Paulo"
}

ele entende que o objeto associado à chave "editora" deve ser convertido para um objeto do tipo Editora.
O processo ocorre de forma recursiva:

  1. Gson cria um objeto Livro.
  2. Lê os campos titulo e autor.
  3. Ao encontrar o campo editora, verifica que seu tipo é Editora.
  4. Cria um objeto Editora.
  5. Preenche os campos nome e cidade.
  6. Associa o objeto Editora ao objeto Livro.

Por isso a conversão acontece automaticamente.
Sobre sua pergunta referente a static, nesse código:

record Editora(String nome, String cidade) {}
record Livro(String titulo, String autor, Editora editora) {}

as duas records foram declaradas no mesmo arquivo, mas não estão aninhadas uma dentro da outra.
Elas são tipos independentes.
Seria uma classe aninhada se estivesse assim:

record Livro(String titulo, String autor, Editora editora) {

    static record Editora(String nome, String cidade) {}
}

Nesse caso, Editora estaria realmente dentro de Livro e seria implicitamente static, pois records aninhadas são estáticas por padrão.
O ponto importante é que o Gson consegue desserializar qualquer objeto cuja estrutura corresponda ao JSON, independentemente de ele estar em um arquivo separado, no mesmo arquivo ou até mesmo aninhado, desde que o tipo seja acessível e possa ser instanciado.
Uma forma interessante de enxergar isso é pensar que o Gson não está olhando para o JSON e tentando "adivinhar" as classes. Ele olha para a classe Livro, encontra o campo Editora editora e usa essa informação para saber exatamente qual tipo deve criar quando encontra o objeto aninhado no JSON.
Excelente observação, pois entender esse mecanismo ajuda bastante quando você começar a trabalhar com APIs que retornam JSONs complexos contendo vários níveis de objetos aninhados.
Avise qualquer dúvida.
Bons estudos.