什么是java序列化这种面试题相信大家都懂了,那么再稍微具体问下java对象哪些成员参与序列化,哪些不参与,怎么自定义序列化和反序列化过程?
2.不可以序列化的内容
对象在序列化过程中要保留当前对象的数据,还会保存它引用到的对象数据,将这个层次结构写入字节流,这就是所谓的深复制了。整个过程中,如果有敏感信息的属性,例如密码,或者带个人隐私的属性,不需要在网络传递或者磁盘存储的,可定义为transient,这样,该字段就不会被序列化了,且该属性值只会保持初始化值。
定义一个类Man,简单起见,就定义2个属性,name,和passwd
class Man implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private String transient passwd;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPasswd() {
return passwd;
}
public void setPasswd(String passwd) {
this.passwd = passwd;
}
public String toString(){
return "名字 :" + name + "密码:"+passwd;
}
对Man对象进行读操作
private void read() {
FileInputStream fis = null;
ObjectInputStream ois = null;
try {
fis = new FileInputStream("d://man.txt");
ois = new ObjectInputStream(fis);
Man man = (Man) ois.readObject();
System.out.println("读取对象内容:" + man.toString());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
try {
fis.close();
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
写操作
private void write() {
FileOutputStream fos = null;
ObjectOutputStream oos = null;
try {
fos = new FileOutputStream("d://man.txt");
oos = new ObjectOutputStream(fos);
Man man = new Man();
man.setName("zhangsan");
man.setPasswd("123");
oos.writeObject(man);
oos.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fos.close();
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
运行代码
public static void main(String[] args) {
App app = new App();
try {
app.write();
app.read();
} catch (Exception e) {
e.printStackTrace();
}
}
结果
读取对象内容:名字 :zhangsan密码:null,可见 通过transient 定义属性 就可以保证该属性不会序列化操作,从而显示初始值null。
有时候密码等关键属性也要序列化,可以自定义序列化的过程,在这过程中可以加密一些信息。
在Man类重写writeObject()和readObject方法就行,例如我把密码写成123+“aaaaaaaaaaaaaaa”再序列化
private void writeObject(ObjectOutputStream out) throws IOException{
out.writeObject(name);
out.writeObject(passwd+"aaaaaaaaaaaaaaa");
}
private void readObject(ObjectInputStream in) throws Exception{
this.name = in.readObject().toString();
this.passwd = in.readObject().toString().replaceAll("aaaaaaaaaaaaaaa", "");
}
运行结果
读取对象内容:名字 :zhangsan密码:123,从而完成解密
一般情况下,是不需要去自定义的,除非想做一些特殊的操作,例如加密,或者增加一些业务逻辑等,都可以使用上面方法进行自定义操作
留言与评论(共有 0 条评论) |