O construtor no-args padrão é obrigatório para o Gson?

O guia do usuário do Gson afirma que devemos definir o construtor no-args padrão para qualquer class funcionar corretamente com o Gson. Ainda mais, no javadoc sobre a class InstanceCreator do Gson disse que a exceção será lançada se tentarmos desserializar a instância do construtor padrão ausente da class e devemos usar o InstanceCreator em tais casos. No entanto, tentei usar o Gson com a class sem o construtor padrão e tanto a serialização quanto a desserialização funcionam sem nenhum problema.

Aqui está o pedaço de código para deserializaiton. Uma class sem construtor não-args:

 public class Mushroom { private String name; private double diameter; public Mushroom(String name, double diameter) { this.name = name; this.diameter = diameter; } //equals(), hashCode(), etc. } 

e um teste:

 @Test public void deserializeMushroom() { assertEquals( new Mushroom("Fly agaric", 4.0), new Gson().fromJson( "{name:\"Fly agaric\", diameter:4.0}", Mushroom.class)); } 

que funciona bem.

Então, minha pergunta é: eu poderia realmente usar o Gson sem precisar ter um construtor padrão ou há alguma circunstância em que isso não funcione?

A partir do Gson 2.3.1.

Independentemente do que a documentação do Gson diga, se sua class não tem um construtor no-args e você não registrou nenhum object InstanceCreater , então ele criará um ObjectConstructor (que constrói seu Object) com um UnsafeAllocator que usa Reflection para obter o método allocateInstance da class sun.misc.Unsafe para criar a instância da sua class.

Essa class Unsafe contorna a falta de construtor no-args e tem muitos outros usos perigosos . estados allocateInstance

Aloque uma instância, mas não execute nenhum construtor. Inicializa a class, se ainda não foi.

Portanto, na verdade, ele não precisa de um construtor e contorna seu construtor de dois argumentos. Veja alguns exemplos aqui .

Se você tiver um construtor no-args, o Gson usará um ObjectConstructor que usa o Constructor padrão chamando

 yourClassType.getDeclaredConstructor(); // ie. empty, no-args 

Meus 2 centavos: Siga o que o Gson diz e crie suas classs com um construtor no-arg ou registre um InstanceCreator . Você pode se encontrar em uma posição ruim usando o Unsafe .

Há uma boa solução na biblioteca de Jackson , conforme descrito aqui:

https://stackoverflow.com/a/11838468/2854723

O objective é informar ao serializador por meio do recurso Mix-Ins quais campos JSON devem ser usados ​​ao usar o construtor com argumentos.

Se essa entidade fizer parte de uma biblioteca externa, você poderá “anotar remotamente” com o recurso Criador .