为什么 java.lang.Void 不可序列化?
默认情况下可以序列化原始“void”,为什么对象“Void”不扩展可序列化?
添加示例:
RootImplementation 将出现编译错误,提示“Void 不在其范围内”,因为它不扩展 Serialized。 虽然“someMethod”会被声明为“void”,但这不会有问题。
public interface Root<R extends Serializable> extends Serializable {
R someMethod();
}
public class RootImplementation implements Root<Void> {
public Void someMethod() {
return null;
}
}
It is possible to serialize the primitive 'void' per default, why does not the object 'Void' extend Serializable?
Added example:
The RootImplementation will have a compilation error saying "Void is not within its bound" since it does not extend Serializable.
Though would 'someMethod' be declared with 'void' it would be no problem.
public interface Root<R extends Serializable> extends Serializable {
R someMethod();
}
public class RootImplementation implements Root<Void> {
public Void someMethod() {
return null;
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
好的,根据您的示例,不,如果您将方法更改为
void
,它将不起作用,因为该方法必须具有返回类型(即使 Java 现在允许在重写方法中使用协变返回类型) 。对void
的讨论使问题变得混乱。您想要做的是将类型参数声明为“将仅返回 null”。 Void 通常是一个不错的选择,但要使 Void 正常工作,返回类型必须是 Object。 Void 不能仅仅因为有人可能想用它来指示类型参数的 null 返回而实现 API 中的每个接口。
可以通过三种方式来看待您的问题:
OK, in response to your example, no if you changed the method to
void
it would not work, as the method has to have a return type (even if Java now allows covariant return types in overridden methods). The discussion ofvoid
confuses the issue.What you want to do is declare a type parameter as a "will just return null." Void is generally a good choice for that, but for Void to work, the return type has to be Object. Void can't implement every interface in the API just because someone might want to use it to indicate a null return on a type parameter.
There are three ways to look at your problem:
javadoc 很清楚:
因为你不能使用它,所以它不需要是可序列化的(除了反射的东西)。
对于第二个问题: void != Void (如果您在非 java 表达式中考虑 != )
是的,
void
是一个关键字,而Void
是一个类。The javadoc is clear:
Because you can not use it, it does not need to be Serializable (except reflection stuff).
And for the second question: void != Void (if you are think about != in a not java expression)
Yes
void
is a keyword andVoid
a class.我将把它作为comminity-wiki 放在这里
你可以(反)序列化
java.lang.Void
b/c 你只能用null 来初始化它。如果类为null
,Java 并不关心该类是否实现了java.io.Serialized
。代码的结果
I will put it here as comminity-wiki
Thou can (de)serialize
java.lang.Void
b/c you can initialize it with null only. Java doesn't care if a class implementsjava.io.Serializable
if it'snull
.Result of the code
引用Javadoc:
由于该类是不可实例化的,因此无法反序列化。因此不需要序列化支持。
To quote the Javadocs:
Since the class is uninstantiable, it cannot be deserialized. Ergo no need for serialization support.
Void 不携带值,因此序列化它是没有意义的。
是的,就像 int != Integer 一样。但是当你序列化和反序列化两个int时,newint==oldint(我的意思是
int
,而不是Integer
!!!)。void
不可能有这样的构造。序列化任何东西都是没有任何意义的。Void doesn't carry a value, hence it makes no sense to serialize it.
True, just as int != Integer. But when you serialize and deserialize two ints, newint==oldint (I mean
int
, notInteger
!!!). No such construct would be possible withvoid
. It just doesn't make any sense to serialize nothing.仅当您有一个 Void 类型的字段时它才有用,这确实没有意义。您还需要实际为其分配一个实例,这又没有意义。只要你不这样做,你就可以序列化包含Void字段的类的实例。为了创建 Void 的实例,您需要使用反射才能使用私有构造函数。
所以你极不可能需要关心 Void 的可序列化性,不是吗?
It'd be only useful if you had a field of type Void, which really makes no sense. You'd also need to actually assign it an instance, which again makes no sense. As long as you don't do it, you can serialize the instance of class containing the Void field. In order to create an instance of Void, you need to use reflection in order to use the private constructor.
So it's extremely improbably you ever need to care about the serializability of Void, isn't it?
其他人已经解释了为什么对于永远无法实例化的类型来实现
Serialized
没有意义,以及为什么void
不是基元或可序列化的。要解决编辑中的代码问题,我认为您应该将
R extends Serialized
更改为仅绑定到R
。大多数可序列化的泛型类型并不要求它们的类型参数是可序列化的...它们只是声明,如果您在其中放入不可序列化的内容,它们将不会也不能序列化。这通常是一个很好的实践,因为在编译器级别过于努力地强制执行可序列化可能会咬伤你(正如你在这里看到的)。Others have explained why it doesn't make sense for a type that can never be instantiated to implement
Serializable
and whyvoid
isn't a primitive or serializable.To address the code in your edit, I think you should just change the
R extends Serializable
bound to justR
. Most generic types that areSerializable
do not require that their type parameters beSerializable
... they simply state that if you put something in them that isn't serializable, they won't be serializable either. This is generally a good practice, as trying too hard to enforce serializability at the compiler level can bite you (as you see here).Void
只是为了表明一个方法只能返回null
,遗憾的是没有办法直接声明 null 类型。对于 jvm Void 只是一个扩展 Object 的普通类,因此不能用于其他类或接口,这使得 Void 对于您的示例毫无用处。由于您的方法不会返回除 null 之外的任何内容,因此您可以将 Void 替换为类似以下内容:
至于调用 void 基元,void 表明缺少值,返回 void 的方法不会返回 void 类型的值,而是实际上不返回返回任何东西。
Void
is only intended to show that a method can only returnnull
, sadly there is no way to declare the null-type directly. For the jvm Void is only a normal class extending Object and as such cannot be used in place for other classes or interfaces, this makes Void for your example useless.Since your method wont return anything but null you could replace Void with something like the following:
As to calling void a primitive, void shows the absence of a value, a method returning void does not return a value of type void instead it literally does not return anything.
如果您使用 apache commons 库,则有一个 org.apache.commons.lang3.ObjectUtils.Null 扩展了 Serialized。
If you are using apache commons library, there's a org.apache.commons.lang3.ObjectUtils.Null which does extend Serializable.