从以下几个方面来讨论这个问题
1、序列化是用来干什么的?
序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容就行流化。简而言之就是为了保存内存中的各种实例对象的状态,并且可以通过反序列化将实例对象的状态再读出来。
2、为什么需要序列化?
为了将对象转换为更加容易传输的格式,减少网络流量的开销。例如,可以序列化一个实例对象,然后使用Http通过Internet在客户端和服务端之间传输该对象,在另外一段,反序列化将从该流中重新构造对象。
3、什么情况下需要序列化?
public class Org { private String orgId; private String orgName; /** * @return 返回 orgId */ public String getOrgId() { return orgId; } /** * @param 对orgId进行赋值 */ public void setOrgId(String orgId) { this.orgId = orgId; } /** * @return 返回 orgName */ public String getOrgName() { return orgName; } /** * @param 对orgName进行赋值 */ public void setOrgName(String orgName) { this.orgName = orgName; } }
public class User implements Serializable { /** * 注释内容 */ private static final long serialVersionUID = -2069026676796654202L; public static String s = "ssss"; private String userName; private String password; private Org org; /** * @return 返回 org */ public Org getOrg() { return org; } /** * @param 对org进行赋值 */ public void setOrg(Org org) { this.org = org; } /** * @return 返回 userName */ public String getUserName() { return userName; } /** * @param 对userName进行赋值 */ public void setUserName(String userName) { this.userName = userName; } /** * @return 返回 password */ public String getPassword() { return password; } /** * @param 对password进行赋值 */ public void setPassword(String password) { this.password = password; } }
public class UserImpl extends User { /** * 注释内容 */ private static final long serialVersionUID = 418270522532375203L; private String confimPassword; /** * @return 返回 confimPassword */ public String getConfimPassword() { return confimPassword; } /** * @param 对confimPassword进行赋值 */ public void setConfimPassword(String confimPassword) { this.confimPassword = confimPassword; } }
<!--------------------------------------------------------------分割线---------------------------------------------------------------!>
public class WriteTest { /** * <一句话功能简述> * <功能详细描述> * @param args * @see [类、类#方法、类#成员] */ public static void main(String[] args) { User user = new UserImpl(); user.setUserName("aaa"); user.setPassword("bbb"); try { FileOutputStream fos = new FileOutputStream("User.bin"); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(user); fos.close(); oos.close(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
通过查看序列化后的文件:
User.bin
com.serializable.UserImpl confimPasswordt Ljava/lang/String;xr com.serializable.User orgt Lcom/serializable/Org;L passwordq userNameq xppt bbbt aaap
我们可以得出以下的结论
1、序列化的内容包括对象的类型信息、对象的属性信息、对象的属性值信息。而对象的方法信息没有被序列化,静态变量也没有被实例化(这个其实也很好理解,序列化是序列化实例对 象的状态信息,而静态变量是属于类型的信息)。
2、当一个对象的实例变量引用其他对象,那么序列化该对象也会把引用对象进行序列化。
3、父类序列化那么子类也自动序列化。
如果我们将User类的实现序列化接口去掉,将UserImpl类的实现序列化接口加上去会怎么样呢?
我这里给出结果
com.serializable.UserImpl confimPasswordt Ljava/lang/String;xpp
我们有没有发现,没有序列化父类的属性以及属性值,我们得出
4、子类序列化,父类没有序列化,则子类序列化时,父类的类型信息、属性以及属性值并不会序列化。
序列化的其他一些特性比如:Transient
Transient 关键字的作用是控制变量的序列化,在变量声明前加上该关键字,可以阻止该变量被序列化到文件中,在被反序列化后,transient 变量的值被设为初始值,如 int 型的是 0,对象型的是 null。
等等,很多信息都可以参考google,这里给出一个觉得比较容易理解的文章的链接http://www.ibm.com/developerworks/cn/java/j-lo-serial/index.html?ca=drs-