作者:Black | 来源:互联网 | 2023-09-17 17:13
1.为什么java对象要序列化?因为对象不可能在jvm中一直存在,内存中序列化的对象就可以将对象保存到其他介质上,比如:硬盘的文件中,也可以进行网络传输,并且反序列化后,
1.为什么java对象要序列化?
因为对象不可能在jvm中一直存在,内存中序列化的对象就可以将对象保存到其他介质上,比如:硬盘的文件中,也可以进行网络传输, 并且反序列化后,数据不会丢失,能够完好地得到该对象.
2.如何序列化?
像enum枚举是默认实现了serializable接口的,它就可以序列化,所以只要任何类实现了序列化接口,它就可以序列化,注意不要用默认的序列化id=1,这样不能保证反序列化后对象的唯一性,应该使用编译器生成的序列化id.
3.如果类实现了序列化接口,那它的所有属性都能序列化吗?
不能,像static静态属性,标识有transient的属性不能序列化
举个例子:
public class SerializeDemo
{
public static void main(String[] args)
{
File file = new File("serializableObj");
writeObject(file);
readObject(file);
}
/**
* @param file
*/
private static void readObject(File file)
{
try
{
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(file));
Object object = objectInputStream.readObject();
System.out.println(object);//直接调用该对象的toString()方法
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
}
}
/**
* @param file
*/
private static void writeObject(File file)
{
try
{
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(file));
objectOutputStream.writeObject(new Person(111, 222, "zhangshang"));
objectOutputStream.close();
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
class Person implements Serializable
{
/**
*
*/
private static final long serialVersiOnUID= 2673648647774732782L;
private int personId; // 注意这里是基本类型
private Integer personNo;
private String personName;
public Person()
{
System.out.println("no param constructor invoke");
}
public Person(int personId, Integer personNo, String personName)
{
this.persOnId= personId;
this.persOnNo= personNo;
this.persOnName= personName;
}
public int getPersonId()
{
return personId;
}
public void setPersonId(int personId)
{
this.persOnId= personId;
}
public String getPersonName()
{
return personName;
}
public void setPersonName(String personName)
{
this.persOnName= personName;
}
@Override
public String toString()
{
return new StringBuffer(this.personId).append(this.personName).append(personNo).toString();
}
public Integer getPersonNo()
{
return personNo;
}
public void setPersonNo(Integer personNo)
{
this.persOnNo= personNo;
}
}
执行结果:
zhangshang222
可以看出int类型的值没有被序列化,因为没有输出它的值,甚至连null也没有输出,而Integer,String,这些类类型都直接或者间接地实现了序列化接口。
那可不可以把该类中int给序列化,不行,序列化是对对象而言的。可不可以把可序列化的Integer变成不能序列化,是可以的,加transient关键字,如果想把transient的属性再序列化回来怎么做,一,把transient去掉,二,如下添加两个方法:
private void writeObject(ObjectOutputStream out) throws IOException
{
out.defaultWriteObject();
out.writeInt(personNo);
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
{
in.defaultReadObject();
persOnNo= in.readInt();
}
还有另一个序列化接口Externalizable
需要我们自己来实现它里面的两个方法,如果没有作实现,任何可以序列化的对象都不会序列化
像如下实现
class Person implements Externalizable
{
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
{
persOnName= (String) in.readObject();
persOnNo= in.readInt();
}
@Override
public void writeExternal(ObjectOutput out) throws IOException
{
out.writeObject(personName);
out.writeInt(personNo);
}
要人工地将需要序列化的对象写进来