从以下几个方面来讨论这个问题
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-