Java 对于没有无参数构造函数的类,数字应该如何扩展?

Java 对于没有无参数构造函数的类,数字应该如何扩展?,java,numbers,serializable,default-constructor,Java,Numbers,Serializable,Default Constructor,我已经实现了几个Java类,它们扩展了抽象的Java.lang.Number类。我不需要立即序列化这些类的对象。但是,我确实希望为这些表示“数字”的类提供数字契约的其余部分。问题是java.lang.Number实现了可序列化。因此,我的类应该提供公共默认(即没有参数)构造函数——我的IDE会抱怨,但编译器仍然会编译我的类。很好,但是为“不可变”对象提供公共默认构造函数需要在出于序列化以外的任何原因调用构造函数时提供默认值——暂时忽略这些类从静态工厂方法返回对象,现在不公开公共构造函数。嗯,在很

我已经实现了几个Java类,它们扩展了抽象的Java.lang.Number类。我不需要立即序列化这些类的对象。但是,我确实希望为这些表示“数字”的类提供数字契约的其余部分。问题是java.lang.Number实现了可序列化。因此,我的类应该提供公共默认(即没有参数)构造函数——我的IDE会抱怨,但编译器仍然会编译我的类。很好,但是为“不可变”对象提供公共默认构造函数需要在出于序列化以外的任何原因调用构造函数时提供默认值——暂时忽略这些类从静态工厂方法返回对象,现在不公开公共构造函数。嗯,在很多情况下,零是一个很好的默认值,但是自然数——即正整数——在其域中不包含零,并且没有一个数字比任何其他数字更“特殊”……好吧……“一”总是“特殊”

等等,等等

我确实研究了BigDecimal如何处理数字和序列化,以确定解决这个问题的“正确”方法。然而,我能够检查的JavaDoc和源代码都揭示了BigDecimal并没有提供“no args”构造函数,尽管它有扩展的Number。认识到:

仅仅因为Sun Microsystems/Oracle以这种方式实施,并不意味着它是“正确的”

我回到基本问题上来:

扩展java.lang.Number的“正确”方法是什么?如果提供“no args”构造函数只是遵循规则的另一种Java约定:

这不是法律,只是个好主意


忽略“约定”是避免这些缺点的最佳答案吗?如果是这样,我如何满足IDE——特别是Intellij——以及任何Java到其他语言或环境转换器的要求,当可序列化性出现问题时,这些转换器可能会选择比Java编译器更严格?

嗯,总有好的ol'NaN'——不是一个数字。如果您可以表示它,也就是说。

我的观点是,人们可能会在以后忘记与Java的内置序列化兼容。它比文本Jackson慢8倍,似乎已经过时了。

您还可以保护空构造函数,这样序列化仍然有效。Sun为BigDecimal所做的是提供readObject和writeObject方法,有关更多详细信息,请参阅

我假设
扩展Number
的类有带参数的构造函数?它们有带参数的私有构造函数,这些参数由公共静态工厂方法调用,这些方法返回新对象或几种常用对象之一,如零或一,因此,它为什么抱怨您没有默认的无参数构造函数。如果不存在构造函数,编译器将添加一个隐式的无参数构造函数。为什么不使用一个私有的无参数构造函数,看看这是否会让IDE安静下来?一个私有的默认构造函数并不会让IDE安静下来——我的一些类扩展了其他类,所以私有构造函数永远不可能是一个完整的解决方案。但是,引发异常的受保护默认构造函数确实“解决”了问题。这仍然是一个缺点,但不是一个让全世界都能看到的缺点……如果我需要完全实现可序列化契约,我本来打算实现readObject和writeObject方法。但是,我的“number”类被编译为两个目标,即使用GWT编译器的JVM和JavaScript。GWT提供的JRE仿真库不提供反射或这些方法的签名所需的类。然而,这是另一天的担忧。在此之前,引发异常的受保护默认构造函数是解决我的问题的最不突出的缺点。谢谢