当前位置: 首页 > 知识库问答 >
问题:

Gson是否必须使用默认无参数构造函数?

公孙胡媚
2023-03-14

Gson用户指南指出,我们应该为任何类定义默认的无参数构造函数,以便正确使用Gson。更重要的是,在Gson的InstanceCreator类的javadoc中说,如果我们试图反序列化缺少默认构造函数的类的实例,将引发异常,在这种情况下,我们应该使用InstanceCreator。然而,我已经尝试在缺少默认构造函数的类中测试使用Gson,并且序列化和反序列化都可以顺利工作。

下面是反序列化的一段代码。没有非参数构造函数的类:

public class Mushroom {
    private String name;
    private double diameter;

    public Mushroom(String name, double diameter) {
        this.name = name;
        this.diameter = diameter;
    }

    //equals(), hashCode(), etc.
}

还有一个测试:

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

这很好用。

所以我的问题是:我真的可以在不需要默认构造函数的情况下使用Gson吗?

共有3个答案

申嘉慕
2023-03-14

举个例子,它可以,因为你的JSON中有所有的值,所以即使他们没有初始化,他们也会覆盖每个变量。但是在许多情况下,可能有一些瞬态字段,或者在JSON中没有值的可选字段。然后,如果您没有无参数构造函数,当有人试图读取该字段时,该字段将保持为null和NPE。

公西俊德
2023-03-14

杰克逊库中有一个很好的解决方案,如下所述:

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

关键是通过Mix-Ins功能告诉序列化程序在使用带参数的构造函数时使用哪个JSON字段。

如果该实体是外部库的一部分,则可以使用Creator功能进行“远程注释”。

盖泽宇
2023-03-14

截至Gson 2.3.1。

不管Gson文档怎么说,如果您的类没有no args构造函数,并且您没有注册任何InstanceCreater对象,然后它将创建一个ObjectConstructor(它构造您的对象)和一个UnsafeAllocator,它使用反射来获取类sun的allocateInstance方法。杂项。不安全创建类的实例。

这个不安全的类绕过了无参数构造函数的缺陷,还有许多其他危险的用途<代码>分配实例状态

分配一个实例,但不要运行任何构造函数。如果尚未初始化该类,则初始化该类。

所以它实际上不需要构造函数,它将绕过你的两个参数构造函数。在这里看到一些例子。

如果你有一个no-args构造函数,Gson将使用一个ObjectConstructor,它通过调用来使用默认的Constructor

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

我的2美分:按照Gson所说的,用无参数构造函数创建类,或者注册一个InstanceCreator。使用不安全,您可能会发现自己处于不利地位。

 类似资料:
  • 问题内容: Gson用户指南指出,我们应该为任何可以正常使用Gson的类定义默认的无参数构造函数。甚至,在Gson 类的javadoc中说,如果我们尝试对缺少默认构造函数的类实例进行反序列化,则会抛出异常,在这种情况下 应 使用该异常。但是,我尝试对缺少默认构造函数的类使用Gson进行测试,并且序列化和反序列化工作都没有任何麻烦。 这是反序列化的代码。没有非参数构造函数的类: 和一个测试: 效果很

  • 问题内容: Gson用户指南指出,我们应该为任何可以正常使用Gson的类定义默认的无参数构造函数。更重要的是,在Gson 类的javadoc中说,如果我们尝试对缺少默认构造函数的类实例进行反序列化,则会抛出异常,并且在这种情况下应使用该异常。但是,我尝试对缺少默认构造函数的类使用Gson进行测试,并且序列化和反序列化工作都没有任何麻烦。 这是反序列化的代码。没有非参数构造函数的类: 和一个测试:

  • 我正在开发一个Spring Boot应用程序(v2.1.5版本),其中h2是内存数据库。我创建了一个简单的项目,主要和只有一个模型人。java只有3个私有字段。我根本没有构造函数,但当我启动应用程序并打开h2控制台时,我仍然能够看到从实体Person创建的表。我从一个SO问题中读到,当我们使用@entity注释时,需要一个无参数构造函数。它是强制性的吗? 人Java语言 主要类别

  • 问题内容: 我的第一个问题是- 构造函数应始终声明为公共吗? 如果我创建一个构造函数该怎么办。 我总是看到构造函数是隐式的。那么为什么构造函数有用呢?还是根本没有用。因为没有人可以调用它,或者永远也不能创建对象(由于构造函数)!这是我的第二个问题。 问题答案: 不, 构造函数 可以是,, 或(根本没有访问修饰符)。 做某事 并不意味着没有人可以访问它。这只是意味着该类之外的任何人都不能访问它。因此

  • 图 6.1 time1.cpp 中的构造函数将 hour、minute 和 second 初始化为 0(即军用时间午夜11时)。 构造函数可以包含默认参数。图 6.8 重新定义 Time 的构造函数,该函数中每个变量的默认参数为0。通过提供构造函数默认参数,即使在构造函数调用中不提供数值,对象也能利用默认参数初始化为一致状态。程序员提供所有参数默认值(或显式不要求参数)的构造函数也称为默认构造函数

  • 实际上,我不明白无参数构造函数和默认构造函数的区别是什么。 在创建名为cFrame的Test对象时,是否调用此类的默认构造函数?