读书人

怎么序列化transient和static修饰的变

发布时间: 2012-08-22 09:50:34 作者: rapoo

如何序列化transient和static修饰的变量
通常情况下,用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.     *     * @throwsIOException 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);}   

读书人网 >编程

热点推荐