如何序列化transient和static修饰的变量_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > 如何序列化transient和static修饰的变量

如何序列化transient和static修饰的变量

 2012/3/23 23:51:12  837062099  程序员俱乐部  我要评论(0)
  • 摘要:通常情况下,用transient和static修饰的变量是不能被序列化的,但是通过在序列化的类中写writeObject(ObjectOutputStreamstream)和readObject(ObjectInputStreamstream)方法,可以实现序列化。有人说static的变量为什么不能序列化,因为static的变量可能被改变。staticfinal的常量可以被序列化。packagedemo.serializable.advance;importjava.io.*
  • 标签:序列化
通常情况下,用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);
	}
   
  • 相关文章
发表评论
用户名: 匿名