- 浏览: 799792 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (248)
- Struts1.x (3)
- Java (24)
- SQL (8)
- 错误汇总/Java (7)
- 错误汇总/JDBC (1)
- 错误汇总/lomboz_eclipse_Hibernate proposals (1)
- 错误汇总/javascript (3)
- 错误汇总/Hibernate + JPA (1)
- 错误汇总/dwr (1)
- hibernate3.X (10)
- Struts2.x (5)
- 概念/JPA (1)
- 概念/JTA (1)
- dwr (1)
- JSTL (1)
- English (6)
- Java/awt (4)
- design_pattern/Observer (2)
- 项目管理 (1)
- Java面试题 (7)
- Linux/Unix (4)
- 服务器/WAS6.0 (1)
- 服务器/WAS6.1 (5)
- 服务器/JBoss (2)
- 收藏 (4)
- 服务器/Tomcat6.X (2)
- 错误汇总/Struts2.X (3)
- JavaRebel (1)
- 小技巧 (3)
- 版本控制 (1)
- 错误汇总/Tomcat6.X (2)
- 错误汇总/Cactus (1)
- HttpUnit (1)
- 错误汇总/Struts1.x (2)
- 数据库/Oracle (6)
- 小技巧/MyEclipse (1)
- javascript (21)
- OGNL (1)
- JSP (2)
- 报表/BIRT (5)
- jquery (6)
- ec:table&ec:side (1)
- Java/Date (1)
- C# (2)
- NC (32)
- oracle (10)
- Ant (1)
- Eclipse (1)
- 迷茫 (1)
- swing (3)
- 数据库/MySQL (2)
- 装机 (3)
- 名词解释/NC (3)
- java/算法 (1)
- HTML (1)
- 分布式 (2)
- flex (5)
- SSI(spring+struts_ibatis) (1)
- UML (1)
- ajax (1)
- Flex 背景透明 (1)
- Android (8)
- 正则 (2)
- linux (1)
最新评论
-
yizishou:
IE9- Only
javascript中createTextRange用法(focus) -
huanzei:
还可以了,po主的第一个方法可行,第二个方法没有试
jsp表格的表头固定不动 -
javams:
Soongtracy 写道方法二完全不行啊亲,你自己有木有试过 ...
jsp表格的表头固定不动 -
mengy163163:
您好,有个问题想请教一下:"birt生成Excel缺 ...
BIRT报表 -
zzy2011266:
楼主,你找到原因了吗?这是为啥?貌似是JVM出bug了
JAVA异常 EXCEPTION_ACCESS_VIOLATION (0xc0000005)
今天在面试中遇到了这个问题,关于为什么要继承序列化这个东西,在网上搜了一下大概了解到
一篇是从BlogJava中看到的,大概内容如下:
为什么要使用序列化?最重要的两个原因是:将对象的状态保存在存储媒体中以便可以在以后重新创建出完全相同的副本;按值将对象从一个应用程序域发送至另一个应用程序域。例如,序列化可用于在 ASP.NET 中保存会话状态,以及将对象复制到 Windows 窗体的剪贴板中。它还可用于按值将对象从一个应用程序域远程传递至另一个应用程序域。本文简要介绍了 Microsoft .NET 中使用的序列化。
一.简介
序列化是指将对象实例的状态存储到存储媒体的过程。在此过程中,先将对象的公共字段和私有字段以及类的名称(包括类所在的程序集)转换为字节流,然后再把字节流写入数据流。在随后对对象进行反序列化时,将创建出与原对象完全相同的副本。
在面向对象的环境中实现序列化机制时,必须在易用性和灵活性之间进行一些权衡。只要您对此过程有足够的控制能力,就可以使该过程在很大程度上自动进行。例如,简单的二进制序列化不能满足需要,或者,由于特定原因需要确定类中那些字段需要序列化。以下各部分将探讨 .NET 框架提供的可靠的序列化机制,并着重介绍使您可以根据需要自定义序列化过程的一些重要功能。
二.持久存储
我们经常需要将对象的字段值保存到磁盘中,并在以后检索此数据。尽管不使用序列化也能完成这项工作,但这种方法通常很繁琐而且容易出错,并且在需要跟踪对象的层次结构时,会变得越来越复杂。可以想象一下编写包含大量对象的大型业务应用程序的情形,程序员不得不为每一个对象编写代码,以便将字段和属性保存至磁盘以及从磁盘还原这些字段和属性。序列化提供了轻松实现这个目标的快捷方法。
公共语言运行时 (CLR) 管理对象在内存中的分布,.NET 框架则通过使用反射提供自动的序列化机制。对象序列化后,类的名称、程序集以及类实例的所有数据成员均被写入存储媒体中。对象通常用成员变量来存储对其他实例的引用。类序列化后,序列化引擎将跟踪所有已序列化的引用对象,以确保同一对象不被序列化多次。.NET 框架所提供的序列化体系结构可以自动正确处理对象图表和循环引用。对对象图表的唯一要求是,由正在进行序列化的对象所引用的所有对象都必须标记为 Serializable(请参阅基本序列化)。否则,当序列化程序试图序列化未标记的对象时将会出现异常。当反序列化已序列化的类时,将重新创建该类,并自动还原所有数据成员的值。
三.按值封送
对象仅在创建对象的应用程序域中有效。除非对象是从 MarshalByRefObject 派生得到或标记为 Serializable,否则,任何将对象作为参数传递或将其作为结果返回的尝试都将失败。如果对象标记为 Serializable,则该对象将被自动序列化,并从一个应用程序域传输至另一个应用程序域,然后进行反序列化,从而在第二个应用程序域中产生出该对象的一个精确副本。此过程通常称为按值封送。
如果对象是从 MarshalByRefObject 派生得到,则从一个应用程序域传递至另一个应用程序域的是对象引用,而不是对象本身。也可以将从 MarshalByRefObject 派生得到的对象标记为 Serializable。远程使用此对象时,负责进行序列化并已预先配置为 SurrogateSelector 的格式化程序将控制序列化过程,并用一个代理替换所有从 MarshalByRefObject 派生得到的对象。如果没有预先配置为 SurrogateSelector,序列化体系结构将遵从下面的标准序列化规则(请参阅序列化过程的步骤)。
四.基本序列化
使用二进制格式化程序执行序列化时,一个类的所有成员变量都将被序列化,即使是那些已被标记为私有的变量。在此方面,二进制序列化不同于 XMLSerializer 类,后者只序列化公共字段。
要使一个类可序列化,最简单的方法是使用 Serializable 属性对它进行标记,如下所示:
[Serializable]
public class MyObject {
public int n1 = 0;
public int n2 = 0;
public String str = null;
}
以下代码片段说明了如何将此类的一个实例序列化为一个文件:
MyObject obj = new MyObject();
obj.n1 = 1;
obj.n2 = 24;
obj.str = "一些字符串";
IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream("MyFile.bin", FileMode.Create,
FileAccess.Write, FileShare.None);
formatter.Serialize(stream, obj);
stream.Close();
本例使用二进制格式化程序进行序列化。您只需创建一个要使用的流和格式化程序的实例,然后调用格式化程序的 Serialize 方法。流和要序列化的对象实例作为参数提供给此调用。类中的所有成员变量(甚至标记为 private 的变量)都将被序列化,但这一点在本例中未明确体现出来。在这一点上,二进制序列化不同于只序列化公共字段的 XML 序列化程序。
将对象还原到它以前的状态也非常容易。首先,创建格式化程序和流以进行读取,然后让格式化程序对对象进行反序列化。以下代码片段说明了如何进行此操作。
IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream("MyFile.bin", FileMode.Open,
FileAccess.Read, FileShare.Read);
MyObject obj = (MyObject) formatter.Deserialize(fromStream);
stream.Close();
// 下面是证明
Console.WriteLine("n1: {0}", obj.n1);
Console.WriteLine("n2: {0}", obj.n2);
Console.WriteLine("str: {0}", obj.str);
上面所使用的 BinaryFormatter 效率很高,能生成非常紧凑的字节流。所有使用此格式化程序序列化的对象也可使用它进行反序列化,对于序列化将在 .NET 平台上进行反序列化的对象,此格式化程序无疑是一个理想工具。需要注意的是,对对象进行反序列化时并不调用构造函数。对反序列化添加这项约束,是出于性能方面的考虑。但是,这违反了对象编写者通常采用的一些运行时约定,因此,开发人员在将对象标记为可序列化时,应确保考虑了这一特殊约定。
如果要求具有可移植性,请使用 SoapFormatter。所要做的更改只是将以上代码中的格式化程序换成 SoapFormatter,而 Serialize 和 Deserialize 调用不变。对于上面使用的示例,该格式化程序将生成以下结果。
<SOAP-ENV:Envelope
xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:SOAP- ENC=http://schemas.xmlsoap.org/soap/encoding/
xmlns:SOAP- ENV=http://schemas.xmlsoap.org/soap/envelope/
SOAP-ENV:encodingStyle=
"http://schemas.microsoft.com/soap/encoding/clr/1.0
http://schemas.xmlsoap.org/soap/encoding/"
xmlns:a1="http://schemas.microsoft.com/clr/assem/ToFile">
<SOAP-ENV:Body>
<a1:MyObject id="ref-1">
<n1>1</n1>
<n2>24</n2>
<str id="ref-3">一些字符串</str>
</a1:MyObject>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
需要注意的是,无法继承 Serializable 属性。如果从 MyObject 派生出一个新的类,则这个新的类也必须使用该属性进行标记,否则将无法序列化。例如,如果试图序列化以下类实例,将会显示一个 SerializationException,说明 MyStuff 类型未标记为可序列化。
public class MyStuff : MyObject
{
public int n3;
}
使用序列化属性非常方便,但是它存在上述的一些限制。有关何时标记类以进行序列化(因为类编译后就无法再序列化),请参考有关说明(请参阅下面的序列化规则)。
五.选择性序列化
类通常包含不应被序列化的字段。例如,假设某个类用一个成员变量来存储线程 ID。当此类被反序列化时,序列化此类时所存储的 ID 对应的线程可能不再运行,所以对这个值进行序列化没有意义。可以通过使用 NonSerialized 属性标记成员变量来防止它们被序列化,如下所示:
[Serializable]
public class MyObject
{
public int n1;
[NonSerialized] public int n2;
public String str;
}
六.自定义序列化
可以通过在对象上实现 ISerializable 接口来自定义序列化过程。这一功能在反序列化后成员变量的值失效时尤其有用,但是需要为变量提供值以重建对象的完整状态。要实现 ISerializable,需要实现 GetObjectData 方法以及一个特殊的构造函数,在反序列化对象时要用到此构造函数。以下代码示例说明了如何在前一部分中提到的 MyObject 类上实现 ISerializable。
[Serializable]
public class MyObject : ISerializable
{
public int n1;
public int n2;
public String str;
public MyObject()
{
}
protected MyObject(SerializationInfo info, StreamingContext context)
{
n1 = info.GetInt32("i");
n2 = info.GetInt32("j");
str = info.GetString("k");
}
public virtual void GetObjectData(SerializationInfo info,
StreamingContext context)
{
info.AddValue("i", n1);
info.AddValue("j", n2);
info.AddValue("k", str);
}
}
在序列化过程中调用 GetObjectData 时,需要填充方法调用中提供的SerializationInfo 对象。只需按名称/值对的形式添加将要序列化的变量。其名称可以是任何文本。只要已序列化的数据足以在反序列化过程中还原对象,便可以自由选择添加至 SerializationInfo 的成员变量。如果基对象实现了 ISerializable,则派生类应调用其基对象的 GetObjectData 方法。
需要强调的是,将 ISerializable 添加至某个类时,需要同时实现 GetObjectData 以及特殊的构造函数。如果缺少 GetObjectData,编译器将发出警告。但是,由于无法强制实现构造函数,所以,缺少构造函数时不会发出警告。如果在没有构造函数的情况下尝试反序列化某个类,将会出现异常。在消除潜在安全性和版本控制问题等方面,当前设计优于SetObjectData 方法。例如,如果将 SetObjectData 方法定义为某个接口的一部分,则此方法必须是公共方法,这使得用户不得不编写代码来防止多次调用 SetObjectData 方法。可以想象,如果某个对象正在执行某些操作,而某个恶意应用程序却调用此对象的 SetObjectData 方法,将会引起一些潜在的麻烦。
在反序列化过程中,使用出于此目的而提供的构造函数将 SerializationInfo 传递给类。对象反序列化时,对构造函数的任何可见性约束都将被忽略,因此,可以将类标记为 public、protected、internal 或 private。一个不错的办法是,在类未封装的情况下,将构造函数标记为 protect。如果类已封装,则应标记为 private。要还原对象的状态,只需使用序列化时采用的名称,从 SerializationInfo 中检索变量的值。如果基类实现了 ISerializable,则应调用基类的构造函数,以使基础对象可以还原其变量。
如果从实现了 ISerializable 的类派生出一个新的类,则只要新的类中含有任何需要序列化的变量,就必须同时实现构造函数以及 GetObjectData 方法。以下代码片段显示了如何使用上文所示的 MyObject 类来完成此操作。
[Serializable]
public class ObjectTwo : MyObject
{
public int num;
public ObjectTwo() : base()
{
}
protected ObjectTwo(SerializationInfo si, StreamingContext context) :
base(si,context)
{
num = si.GetInt32("num");
}
public override void GetObjectData(SerializationInfo si,
StreamingContext context)
{
base.GetObjectData(si,context);
si.AddValue("num", num);
}
}
切记要在反序列化构造函数中调用基类,否则,将永远不会调用基类上的构造函数,并且在反序列化后也无法构建完整的对象。对象被彻底重新构建,但是在反系列化过程中调用方法可能会带来不良的副作用,因为被调用的方法可能引用了在调用时尚未反序列化的对象引用。如果正在进行反序列化的类实现了 IDeserializationCallback,则反序列化整个对象图表后,将自动调用 OnSerialization 方法。此时,引用的所有子对象均已完全还原。有些类不使用上述事件侦听器,很难对它们进行反序列化,散列表便是一个典型的例子。在反序列化过程中检索关键字/值对非常容易,但是,由于无法保证从散列表派生出的类已反序列化,所以把这些对象添加回散列表时会出现一些问题。因此,建议目前不要在散列表上调用方法。
七.序列化过程的步骤
在格式化程序上调用 Serialize 方法时,对象序列化按照以下规则进行:
检查格式化程序是否有代理选取器。如果有,检查代理选取器是否处理指定类型的对象。如果选取器处理此对象类型,将在代理选取器上调用 ISerializable.GetObjectData。
如果没有代理选取器或有却不处理此类型,将检查是否使用 Serializable 属性对对象进行标记。如果未标记,将会引发 SerializationException。
如果对象已被正确标记,将检查对象是否实现了 ISerializable。如果已实现,将在对象上调用 GetObjectData。
如果对象未实现 Serializable,将使用默认的序列化策略,对所有未标记为 NonSerialized 的字段都进行序列化。 八.版本控制
.NET 框架支持版本控制和并排执行,并且,如果类的接口保持一致,所有类均可跨版本工作。由于序列化涉及的是成员变量而非接口,所以,在向要跨版本序列化的类中添加成员变量,或从中删除变量时,应谨慎行事。特别是对于未实现 ISerializable 的类更应如此。若当前版本的状态发生了任何变化(例如添加成员变量、更改变量类型或更改变量名称),都意味着如果同一类型的现有对象是使用早期版本进行序列化的,则无法成功对它们进行反序列化。
如果对象的状态需要在不同版本间发生改变,类的作者可以有两种选择:
实现 ISerializable。这使您可以精确地控制序列化和反序列化过程,在反序列化过程中正确地添加和解释未来状态。
使用 NonSerialized 属性标记不重要的成员变量。仅当预计类在不同版本间的变化较小时,才可使用这个选项。例如,把一个新变量添加至类的较高版本后,可以将该变量标记为 NonSerialized,以确保该类与早期版本保持兼容。
九.序列化规则
由于类编译后便无法序列化,所以在设计新类时应考虑序列化。需要考虑的问题有:是否必须跨应用程序域来发送此类?是否要远程使用此类?用户将如何使用此类?也许他们会从我的类中派生出一个需要序列化的新类。只要有这种可能性,就应将类标记为可序列化。除下列情况以外,最好将所有类都标记为可序列化:
所有的类都永远也不会跨越应用程序域。如果某个类不要求序列化但需要跨越应用程序域,请从 MarshalByRefObject 派生此类。
类存储仅适用于其当前实例的特殊指针。例如,如果某个类包含非受控的内存或文件句柄,请确保将这些字段标记为 NonSerialized 或根本不序列化此类。
某些数据成员包含敏感信息。在这种情况下,建议实现 ISerializable 并仅序列化所要求的字段。
另外一篇是从JavaEye中看到的
经常看到有些类调用了Serializable接口,而有些类又没有调用Serializable接口。那么什么情况下要调用Serializable接口。
首先来了解一下Serializable。(类通过实现 java.io.Serializable 接口以启用其序列化功能。未实现此接口的类将无法使其任何状态序列化或反序列化。序列化接口Serializable没有方法或字段,仅用于标识可序列化的语义)
实现了Serializable接口的对象,可将它们转换成一系列字节,并可在以后完全恢复回原来的样子。这一过程亦可通过网络进行。这意味着序列化机制能自动补偿操作系统间的差异。换句话说,可以先在Windows机器上创建一个对象,对其序列化,然后通过网络发给一台Unix机器,然后在那里准确无误地重新“装配”。不必关心数据在不同机器上如何表示,也不必关心字节的顺序或者其他任何细节。
serialization主要用来支持2种主要的特性:
1、RMI(Remote method invocation)。RMI允许象在本机上一样操作远程机器上的对象。当发送消息给远程对象和调用远程方法时,就需要用到serializaiton机制来发送参数和接收返回值。
2、保存信息。在某个时候把状态信息保存起来,以便以后某个时候能恢复这些状态信息。
Hibernaet和EJB中的实体Bean就用到了上面两个特性。
另外:保存的时候不仅能保存对象的副本,而且还会把对象里面所引用的对象也保存起来,以此类推。就像在编译某个类一样,会涉及到所用到的所有类。但是所引用的对象也必须是可序列化的,不然会抛NotSerializableException异常。
下面来写个例子:(A和B类都是可序列化的,WriteObj:将A序列化,ReadObj:将A反序列化)
Java代码
- package woxingwosu;
- import java.io.Serializable;
- public class A implements Serializable{
- private String name="my name is a";
- private B b=null;
- A(){
- b=new B();
- }
- public B getB() {
- return b;
- }
- public void setB(B b) {
- this.b = b;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public String show(){
- return "a.toString <a.name=\""+this.name+"\" a.b.name=\""+this.b.getName()+"\">"
- +"\na="+this.toString()+" b="+this.b.toString();
- }
- }
Java代码
- package woxingwosu;
- import java.io.Serializable;
- public class B implements Serializable{
- private String name="my name is B";
- B(){}
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- }
Java代码
- package woxingwosu;
- import java.io.FileOutputStream;
- import java.io.ObjectOutputStream;
- /**
- * 写Object(系列化)
- * @author 我行我素
- */
- public class WriteSeri {
- public static void main(String[] args) {
- ObjectOutputStream outObj=null;
- try{
- FileOutputStream outStr=new FileOutputStream("obj.txt");
- outObj=new ObjectOutputStream(outStr);
- A a=new A();
- outObj.writeObject(a);
- System.out.println("write obj :"+a.show());
- outObj.flush();
- }catch(Exception e){
- e.printStackTrace();
- }finally{
- try{
- if(outObj!=null)
- outObj.close();
- }catch(Exception e){
- e.printStackTrace();
- }
- }
- }
- }
Java代码
- package woxingwosu;
- import java.io.FileInputStream;
- import java.io.ObjectInputStream;
- /**
- * 读Object(反系列化)
- * @author 我行我素
- */
- public class ReadSeri {
- public static void main(String[] args) {
- ObjectInputStream inObj=null;
- try{
- FileInputStream inStr=new FileInputStream("obj.txt");
- inObj=new ObjectInputStream(inStr);
- A a=(A)inObj.readObject();
- System.out.println("read Object :"+a.show());
- }catch(Exception e){
- e.printStackTrace();
- }finally{
- try{
- if(inObj!=null)
- inObj.close();
- }catch(Exception e){
- e.printStackTrace();
- }
- }
- }
- }
首先,我们运行WriteObj,实现序列化,得到输出结果
write obj :a.toString <a.name="my name is a" a.b.name="my name is B">
a=woxingwosu.A@a90653 b=woxingwosu.B@de6ced
然后我们再运行ReadObj,实现反序列化,得到输出结果
read Object :a.toString <a.name="my name is a" a.b.name="my name is B">
a=woxingwosu.A@a90653 b=woxingwosu.B@de6ced
官方文档:如果可序列化类未显式声明 serialVersionUID,则序列化运行时将基于该类的各个方面计算该类的默认 serialVersionUID 值,如“Java(TM) 对象序列化规范”中所述。不过,强烈建议 所有可序列化类都显式声明 serialVersionUID 值,原因计算默认的 serialVersionUID 对类的详细信息具有较高的敏感性,根据编译器实现的不同可能千差万别,这样在反序列化过程中可能会导致意外的 InvalidClassException。因此,为保证 serialVersionUID 值跨不同 java 编译器实现的一致性,序列化类必须声明一个明确的 serialVersionUID 值。还强烈建议使用 private 修改器显示声明 serialVersionUID(如果可能),原因是这种声明仅应用于立即声明类 -- serialVersionUID 字段作为继承成员没有用处。
刚才写的例子中就没有用到serialVersionUID,这时JVM会根据类名、接口名、成员方法及属性等来生成一个64位的哈希字段作为serialVersionUID。但是如果序列化和反序列化的JVM版本不一样的话,还是显示写上serialVersionUID安全。
发表评论
-
Swing 各种提示框
2015-08-23 15:52 3126Swing提供了JOptionPane类 ... -
得到指定月的第一天和最后一天
2013-10-15 11:15 3516Calendar calendar = Calendar. ... -
java中常见字符串的正则表达式匹配
2013-09-13 08:51 6828正则表达式是一个字符串,这个字符串可以来描述或者匹配一 ... -
getPhysicalNumberOfCells 与 getLastCellNum的区别
2013-09-05 15:45 5023用org.apache.poi的包做excel导入,无意间发 ... -
JSON日期格式转换
2013-03-27 09:34 2147默认JSON对DATE类型会转换成一个多属性对象, 而不是单 ... -
JAVA判断当前日期是星期几
2013-02-05 14:18 3034/** * 判断当前日期是星期几< ... -
一个数的n次方
2013-02-05 13:36 1012public class NumberUtils { ... -
java中进行二进制,八进制,十六进制,十进制间进行相互转换
2013-02-05 13:34 5243十进制转成十六进制: Integer.toHexString( ... -
指定日期是星期几
2011-02-24 13:26 1230代码: public void week ... -
计算指定年份里月份中的天数
2011-02-23 20:56 1611代码: public void setDate(int ... -
单例与静态的使用
2011-02-22 14:59 1658关于这个问题,下面是 ... -
使用apache的IOUtils类完成文件下载(FileDownload)程序
2010-09-16 23:06 11172package com.test; import ... -
java读取文件路径的几种方法,java 的Class中获得相对路径,绝对路径的方法
2010-09-10 12:16 3287System.out.println("** ... -
System.getProperty()参数大全
2010-09-02 16:48 1249java.version Java Runtime Envir ... -
java 注释换行
2010-08-06 11:42 4283java 注释换行 只适用于doc格式的注释 ... -
java 循环map
2010-03-16 16:17 4802转: 根据JDK5的新特性,用For循环Map,例如循 ... -
关键字volatile
2010-02-24 10:54 1137synchronize建立内存屏障,使其能够抑制内存指令的重排 ... -
java的值传递
2010-01-13 14:10 1083@Test public void TestColl ... -
java内部类有什么好处?为什么需要内部类?
2009-11-17 15:43 2365首先举一个简单的例子,如果你想实现一个接口,但是这个接口中的一 ... -
java中判断字符串是否数字的两种方法
2009-07-20 16:38 4996判断字符串是不是数字,大家可能会用一些java自带的方法,也有 ...
相关推荐
1. 实现序列化:创建一个实现了`Serializable`接口的对象,然后使用`SerializationUtils.serialize(obj)`(来自Commons Lang)将其序列化为字节数组。 2. 存储序列化后的对象:使用Jedis的`set(key, bytes)`方法将...
JavaBean 实现用户登录界面 ...* JavaBean 可以实现Serializable 接口,方便了数据的序列化和反序列化。 使用 JavaBean 实现用户登录验证可以提高系统的安全性和可维护性,并且可以提高开发效率和代码的可读性。
为了使 JavaBean 能够被序列化,需要让该类实现 `Serializable` 接口。这表明该类的对象支持序列化过程。序列化过程中,对象的所有非 `transient` 非静态成员变量都会被保存。`transient` 关键字用于标记不希望被...
实现Java序列化的方式非常简单,只需要让一个类实现`Serializable`接口。例如: ```java public class Cat implements Serializable { private String name; public Cat() { this.name = "new cat"; } // ...
3. **序列化**:为了支持持久化或跨网络传输,JavaBean可以实现Serializable接口。 在用户管理的场景中,我们通常需要创建一个User类,这个类将包含如ID、用户名、密码、电子邮件等属性。接下来,我们将讨论如何...
- **序列化支持**:JavaBean可以通过实现`Serializable`接口来支持序列化,以便持久化对象状态。 2. **JavaBean在数据库操作中的应用** - **数据访问对象(DAO)模式**:JavaBean常被用于实现DAO层,提供对数据库...
同时,JavaBean默认实现了Serializable接口,可被序列化和反序列化,方便在网络间传输或持久化存储。 在描述中提到的“可直接用”,意味着这个JavaBean可能已经预设了一些常用的功能,可以直接在项目中导入和使用。...
3. **序列化**:通常,JavaBean会实现`java.io.Serializable`接口,这样它们就可以被序列化,便于持久化或跨网络传输。 4. **属性访问器和修改器**:除了基本的getter和setter,JavaBean还可能包含is方法(对于布尔...
4. 为了让其他组件可以识别和使用JavaBean,可以实现Serializable接口,使其可序列化。 JavaBean的注解: Java 5引入了注解(Annotation),使得JavaBean的创建更加简洁。例如,使用`@BeanProperties`可以自动生成...
3. **可序列化**:JavaBean需要实现`Serializable`接口,以允许其对象能够在网络中传输或保存到磁盘。实现这个接口后,JavaBean的对象可以被序列化和反序列化。 4. **属性的默认值**:JavaBean可以提供属性的默认值...
5. **序列化支持**:如果需要持久化 JavaBean 对象,那么需要实现 Serializable 接口,以便能够被序列化和反序列化。 BDK 作为测试工具,可能提供了以下功能: 1. **属性检查**:可以检查 JavaBean 的属性值,验证 ...
在Java中,序列化主要通过实现`Serializable`接口来完成。以下是几种常见的Java序列化方式的详细解释: 1. **Java原生序列化** Java原生序列化是最基础的序列化方式,适用于Java标准库中的对象。要进行序列化,...
在我们的`Person`类中,我们没有显式地实现这个接口,因为JavaBean默认就是可序列化的。如果自定义类没有实现`Serializable`,在尝试序列化时会抛出异常。 总结来说,本案例通过Java Socket实现了客户端和服务器...
3. **可序列化**:为了能够在网络中传输或持久化存储JavaBean,需要实现Serializable接口。 4. **命名规则**:属性、getter和setter方法的命名遵循驼峰命名法,如属性名为`username`,则对应的getter方法为`...
此外,JavaBean还需要满足序列化,即实现Serializable接口,以便在网络中传输或持久化存储。 2. **JavaBean的特性**: - **封装性**:JavaBean通过私有变量和公共的getter与setter方法封装数据,确保数据安全。 -...
4. **序列化**:JavaBean通常实现Serializable接口,允许对象的状态被序列化和反序列化。 5. **事件处理**:JavaBean可能支持事件监听机制,允许其他组件订阅并响应Bean的特定事件。 在Java开发中,JavaBean广泛...
4. **序列化(Serializable)**:为了实现持久化或者在网络间传输,JavaBean应实现java.io.Serializable接口。 5. **文档注释(Documentation)**:使用Javadoc注释,提供关于类、属性和方法的详细说明,便于工具...
使用Java的对象序列化方法比较简单,只需要把实现Serializable接口,该对象就可以被序列化。序列化把对象转换成一组byte,这样日后要用这个对象时候,就能把这些byte数据恢复出来,并重新构建原来的对象了。 ### ...