java序列化深入

一.目的:
网络传输对象,数据库存储对象,文件存储对象时都需要实现serializable

序列化id使用:
serialVersionUID,反序列化时如果这个id与序列化时id不同会报错:
java.io.InvalidClassException: jvm.Product; local class incompatible: stream classdesc serialVersionUID = 1, local class serialVersionUID = 2

这样可以使之后反序列化程序在使用这个旧的序列化对象时,抛错。

二.注意点:
1.静态对象及transient不序列化,序列化仅针对对象变量
2.若子类有实现serializable接口,父类没有,在序列化时只会序列化子类相关变量
原因:如果这时父类也实现,会导致所有相关父类都序列化。

3.相反,若一个父类已实现serializable,则序列化子类时,父类及子类相关的变量都会序列化。
即序列化具有继承特性。

4.在反序列化时,父类必须要有默认构造器,否则会报错
no valid constructor

5.有些字段序列化时要求加密怎么处理
对象序列化过程:
a.虚拟机尝试调用要序列化类里的  readObject方法(用于个性化),没有则调用ObjectOutputStream的defaultReadFields
对象反序列化过程:
a.虚拟机尝试调用反序列化的writeObject方法,没有则调用ObjectInputStream的defaultWriteFields

所有可以利用这两个个性化方法,这也是设计时根据业务场景,提供一些方法让使用方能够个性化。

6.java序列化的存储优化
当写入两次同一个对象时,对应保存的对象内存只会有一份,而只会增加引用。
这样做目的是为了节省存储空间。

三.加密字段使用
bankCard类通过writeObject方法来 加密银行卡号,readObject来解密银行卡号。

public class BankCard implements Serializable {

private static final long serialVersionUID = 1L;

private String cardNo;

private void writeObject(ObjectOutputStream out) {
try {

/**
* 1.验证
*/
if (cardNo == "") {
return;
}

/**
* 2.加密
*/
PutField putField = out.putFields();
long cardNoLong = Long.valueOf(cardNo);
cardNoLong = cardNoLong + 1;

String encryptCardNo = String.valueOf(cardNoLong);
putField.put("cardNo", encryptCardNo);

/**
* 3.一定要调用这个,将相应字段序列化到目的地
*/
out.writeFields();
} catch (IOException e) {
e.printStackTrace();
}
}

private void readObject(ObjectInputStream in) {
try {
/**
* 1.校验
*/
GetField getField = in.readFields();
String cardNoBefore = (String) getField.get("cardNo", "");
if (cardNoBefore == "") {
return;
}
System.out.println("=解密前:" + cardNoBefore);

/**
* 2.解密
*/
long cardNoLong = Long.valueOf(cardNoBefore);
cardNoLong = cardNoLong - 1;
this.cardNo = String.valueOf(cardNoLong);
System.out.println("=解密后:" + cardNo);

} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}

public String getCardNo() {
return cardNo;
}

public void setCardNo(String cardNo) {
this.cardNo = cardNo;
}

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值