java 为什么一个类要实现Serializable接口?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7298782/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why does a class implements Serializable interface?
提问by John Cooper
@Entity
public class Husband implements Serializable {
@Id
private int id;
private String name;
@OneToOne
private Wife wife;
}
@Entity
public class Wife implements Serializable {
@Id
private int id;
private String name;
@OneToOne(mappedBy="wife")
private Husband husband;
}
- What is
Serializable
in broad term? - Why does a class implements
Serializable
interface? - Why does the husband member alone have @OnetoOne(mappedBy ="Wife"), but the wife member does not have @OnetoOne(mappedBy="husband")
Serializable
广义上是什么?- 为什么类要实现
Serializable
接口? - 为什么只有丈夫成员有@OnetoOne(mappedBy ="Wife"),而妻子成员没有@OnetoOne(mappedBy="husband")
回答by Swaranga Sarma
Serialization, in broad terms, is the way Java provides developers to persist the state of any object to a persistent store.
If a developer wants that for some reason instance of his coded class should be persisted to a backing store, then the class needs to be declared as implementing Serializable.
The above code represents a One to One relationship between a Husband and a Wife. Which basically means that each wife is related to one husband and each husband is related to one wife. :-) Also in the above relationship, the Husband is the master of the relationship [in Entity-Relationship terms] and that is why Wife says that it is mapped/associated to Husband by the Husband and not the other way around. Which means Husband identifies its wife and not the other way around.
从广义上讲,序列化是 Java 为开发人员提供的将任何对象的状态持久化到持久存储的方式。
如果开发人员出于某种原因希望将其编码类的实例持久化到后备存储,则需要将该类声明为实现 Serializable。
上面的代码代表了丈夫和妻子之间的一对一关系。这基本上意味着每个妻子与一个丈夫有关,每个丈夫与一个妻子有关。:-) 同样在上述关系中,丈夫是关系的主人[在实体关系方面],这就是为什么妻子说它是由丈夫映射/关联到丈夫的,而不是相反。这意味着丈夫识别其妻子,而不是相反。
回答by phihag
1) The Serializable
interface is just a marker. It means that objects can be serialized, i.e. they can be represented as a bit string and restored from that bit string.
1)Serializable
界面只是一个标记。这意味着对象可以被序列化,即它们可以表示为一个位串并从该位串中恢复。
For example, both of your classes are serializable because they can be represented as a bit string (or regular string). On the other hand, a class that represents a file handle given out by the operating system can not be serialized: As soon as the program is finished, that handle is gone, and there is no way to get it back. Reopening the file by file name is not guaranteed to work, since it may have been deleted/moved/changed permissions in the meantime.
例如,您的两个类都是可序列化的,因为它们可以表示为位字符串(或常规字符串)。另一方面,代表操作系统给出的文件句柄的类不能被序列化:程序一完成,句柄就消失了,没有办法把它找回来。不能保证按文件名重新打开文件有效,因为在此期间它可能已被删除/移动/更改权限。
2) Serializing objects that don't implement the Serializable interface will result in a NotSerializableException
being thrown.
2) 序列化没有实现 Serializable 接口的对象将导致NotSerializableException
被抛出。
3) According to the documentation:
3)根据文档:
mappedBy
This element is only specified on the inverse (non-owning) side of the association.
mappingBy
此元素仅在关联的反向(非拥有)侧指定。
回答by Robin
The interface Serializablehelps to persist the state of an object instance.
According to the jpa specification:
"If an entity instance is to be passed by value as a detached object (e.g., through a remote interface), the entity class must implement the Serializable interface" - JSR 220 Persistence - see 2.1 Requirements on the Entity Class
According to the java ee documentation:
"The field that owns the relationship. This element is only specified on the inverse (non-owning) side of the association." - Java EE 6 Documentation
Serializable接口有助于保持对象实例的状态。
根据jpa规范:
“如果实体实例要作为分离对象按值传递(例如,通过远程接口),实体类必须实现可序列化接口” - JSR 220 持久性 - 参见 2.1 实体类的要求
根据 java ee 文档:
“拥有关系的字段。此元素仅在关联的反向(非拥有)侧指定。” - Java EE 6 文档
回答by WesternGun
I just want to answer the third question because it's not fully explained.
我只想回答第三个问题,因为它没有完全解释。
Here is your question:
这是你的问题:
Why does the husband member alone have @OnetoOne(mappedBy="Wife"), but the wife member does not have @OnetoOne(mappedBy="husband")
为什么只有丈夫成员有@OnetoOne(mappedBy="Wife"),而妻子成员没有@OnetoOne(mappedBy="husband")
First, there is something wrong here: it should be:
@OneToOne(mappedBy="wife")
, not . Note that Wife
mappedBy
should be followed by the attributewife
of the Husband
class, not the classWife
, neither the Husband
class name, although the Husband
class is the owner. In the document of Hibernateis said:
首先,这里有问题:它应该是:
@OneToOne(mappedBy="wife")
,而不是。需要注意的是Wife
mappedBy
应遵循的属性wife
中的Husband
类,而不是类Wife
,既没有Husband
类名,虽然Husband
类是所有者。在Hibernate的文档中说:
mappedBy refers to the property name of the association on the owner side.
mappingBy 指的是所有者侧关联的属性名称。
Second, one thing to have in mind is, there are two kinds of relationship when we do the database mapping: unidirectionaland bidirectional. We use unidirectional relationship, when we only want one part handle/maintain this relationship, but from the other side, we are not interested in getting the data of this side. In your example, if we just want an unidirectional relationship from Husband
to Wife
class, we only want to know, by having an object of type Husband
, who is his wife(by its getWife()
method), but we are not interested in knowing one lady's husband.
其次,要记住的一件事是,我们在进行数据库映射时有两种关系:单向和双向。我们使用单向关系,当我们只想要一个部分处理/维护这个关系,但从另一侧,我们对获取这一侧的数据不感兴趣。在你的例子中,如果我们只是想要一个从Husband
toWife
类的单向关系,我们只想知道,通过拥有一个类型的对象Husband
,谁是他的妻子(通过它的getWife()
方法),但我们对了解一位女士的丈夫不感兴趣。
Under this circumstance, we can code like this:
(note that in class Husband
we have attribute of Wife
type, but in Wife
class we don'thave attribute of Husband
type)
在这种情况下,我们可以这样编码:(注意,在类中Husband
我们有Wife
类型的属性,但在Wife
类中我们没有Husband
类型的属性)
Husband.java:
老公.java:
@Entity
public class Husband implements Serializable {
...
@OneToOne
//note that @JoinColumn is necessary when mapping,
//and although in the table you may have columns like
//`ID_WIFE` in table of Husband, in Java it's not a number
//attribute, it's an attribute of `Wife` type.
@JoinColumn(name="idWife")
private Wife wife;
}
Wife.java:
妻子.java:
@Entity
public class Wife implements Serializable {
@Id
private int id;
private String name;
//We can omit the attribute `husband` of `Husband` type,
//because we are not interested in it. Or, we don't need
//to map in the owned side, because it's unidirectional.
}
But, if we want to have an bidirectional relationship, we have to map in both side and in the owned side, mappedBy
is needed before the attribute owned.
但是,如果我们想有一个双向关系,我们必须在双方和拥有方都进行映射,mappedBy
需要在拥有的属性之前。
We remain the Husband
side intact, and we change the Wife.java
:
我们保持Husband
一边完好无损,我们改变了Wife.java
:
Wife.java:
妻子.java:
@Entity
public class Wife implements Serializable {
@Id
private int id;
private String name;
@OneToOne(fetch=FetchType.LAZY, mappedBy="wife")
private Husband husband;
}
Check this page: https://en.wikibooks.org/wiki/Java_Persistence/OneToOne, it explains it all in an understandable way.
检查此页面:https: //en.wikibooks.org/wiki/Java_Persistence/OneToOne,它以易于理解的方式解释了这一切。
Third, just a little note: the owner side, is commonly the class of a table with a FK of another table. Or, we just remember: the owner owns it all, so it also has the FK in its table.
第三,稍微说明一下:owner方,一般是一个表的class,另一个表的FK。或者,我们只记得:所有者拥有这一切,因此它的表中也有 FK。