通常情况下,用transient和static修饰的变量是不能被
序列化的,但是通过在序列化的类中写writeObject(ObjectOutputStream stream)和readObject(ObjectInputStream stream)方法,可以实现序列化。
有人说static的变量为什么不能序列化,因为static的变量可能被改变。
static final的常量可以被序列化。
package demo.serializable.advance;
import java.io.*;
public class OverrideSerial implements Serializable {
private static final long serialVersionUID = -1608783310676957433L;
private static int count; // 用于计算OverrideSerial对象的数目
private static final int MAX_COUNT = 1000;
private String name;
private transient String password = "origin";
static {
System.out.println("调用OverrideSerial类的静态代码块 ");
}
public OverrideSerial() {
System.out.println("调用OverrideSerial类的不带参数的构造方法 ");
count++;
}
public OverrideSerial(String name, String password) {
System.out.println("调用OverrideSerial类的带参数的构造方法 ");
this.name = name;
this.password = password;
count++;
}
/**
* 加密数组,将buff数组中的每个字节的每一位取反 例如13的二进制为00001101,取反后为11110010
*/
private byte[] change(byte[] buff) {
for (int i = 0; i < buff.length; i++) {
int b = 0;
for (int j = 0; j < 8; j++) {
int bit = (buff[i] >> j & 1) == 0 ? 1 : 0;
b += (1 << j) * bit;
}
buff[i] = (byte) b;
}
return buff;
}
private void writeObject(ObjectOutputStream stream) throws IOException {
stream.defaultWriteObject(); // 先按默认方式序列化
stream.writeObject(change(password.getBytes()));
stream.writeInt(count);
}
private void readObject(ObjectInputStream stream) throws IOException,
ClassNotFoundException {
stream.defaultReadObject(); // 先按默认方式反序列化
byte[] buff = (byte[]) stream.readObject();
password = new String(change(buff));
count = stream.readInt();
}
public String toString() {
return "count= " + count + " MAX_COUNT= " + MAX_COUNT + " name= "
+ name + " password= " + password;
}
public static void main(String[] args) throws IOException,
ClassNotFoundException {
FileOutputStream fos = new FileOutputStream("/OverrideSerial.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);
OverrideSerial osInput1 = new OverrideSerial("leo1","akiy1231");
OverrideSerial osInput2 = new OverrideSerial("leo2","akiy1232");
OverrideSerial osInput3 = new OverrideSerial("leo3","akiy1233");
oos.writeObject(osInput1);
oos.writeObject(osInput2);
oos.writeObject(osInput3);
oos.flush();
oos.close();
count =100;
osInput1.name="change";
FileInputStream fis = new FileInputStream("/OverrideSerial.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
OverrideSerial osOutput1 = (OverrideSerial) ois.readObject();
System.out.println(osOutput1.toString());
OverrideSerial osOutput2 = (OverrideSerial) ois.readObject();
System.out.println(osOutput2.toString());
OverrideSerial osOutput3 = (OverrideSerial) ois.readObject();
System.out.println(osOutput3.toString());
}
}
关于defaultWriteObject(),是jdk内部的类,即把非静态和非transient的变量序列化。
/**
* Write the non-static and non-transient fields of the current class to
* this stream. This may only be called from the writeObject method of the
* class being serialized. It will throw the NotActiveException if it is
* called otherwise.
*
* @throws IOException if I/O errors occur while writing to the underlying
* <code>OutputStream</code>
*/
public void defaultWriteObject() throws IOException {
if (curObj == null || curDesc == null) {
throw new NotActiveException("not in call to writeObject");
}
bout.setBlockDataMode(false);
defaultWriteFields(curObj, curDesc);
bout.setBlockDataMode(true);
}