`
837062099
  • 浏览: 111435 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

如何序列化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.
     *
     * @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);
	}
   
分享到:
评论

相关推荐

    java8集合源码分析-Outline:大纲

    修饰变量 方法 静态块(初始化块 构造函数 ) 静态内部类() 静态导包 final() transient() foreach循环原理() volatile底层实现() equals和hashcode(, ) string,stringbuffer和stringbuilder(,,,, ) 伪泛型(, , ) 自动...

    【后端】java基础(5.4)java高级基础之java的修饰符——非访问控制符

    上章讲了访问控制符,这章开始讲非访问控制符。 java中的非访问修饰符的作用各不一样,据我所知常用的有六种: static final abstract synchronized volatile ...被static修饰的方法我们称为静态方

    Java面向对象程序设计(“方法”相关文档)共57张.pptx

    成员变量的声明格式: [&lt;修饰符&gt;] [static] [final] [transient] &lt;变量类型&gt; &lt;变量名&gt; static: 表示是一个类成员变量(静态变量); final: 表示是一个常量; (最终成员变量) 例:final double PI=3.1415926; ...

    Java 语言基础 —— 非常符合中国人习惯的Java基础教程手册

    创建对象包括声明、实例化和初始化三方面的内容。通常的格式为 : 1. 声明对象 对象声明实际上是给对象命名,也称定义一个实例变量。对象声明的一般格式为: type name 其中,type 是一个类的类名,用它声明的对象将...

    【05-面向对象(下)】

    •局部内部类不能在外部类以外的地方使用,那么局部内部类也不能使用访问控制符和static修饰 匿名内部类 •匿名内部类适合创建那种只需要一次使用的类,定义匿名内部类的语法格式如下: •new 父类构造器...

    最全java考试简答题

    protected,final,throw,super,synchronized,static,finally,abstract,transient,instanceof 答:protected`: `protected` 是 Java 中的一种访问修饰符,它用于指定一个成员变量或方法 可以被同一包内的类和所有子类...

    单例模式简介

    知识回顾 修饰符:  权限修饰符:public、 protected、默认不写、private   public:共有的、当前工程的任意位置都能... 修饰变量:只有一次赋值的机会、赋值之后值不能发生改变  属性:要求必须赋初始值、不能

    java面试800题

    Q0043 java相关概念 "static:静态,无需实例化,可直接引用,全局只有一份copy,修饰变量和方法 final:最终的,不可继承、不可修改,修饰变量、方法、类 volatile:volatile变量表示保证它必须是与主内存保持一致,...

    java经典面试2010集锦100题(不看你后悔)

    C) 程序能通过编译,运行时将打印出0/0,因为在Java中int型变量day和month默认为0。 D) 以上说法都不正确。 题目10:c 下面关于继承的描述正确的一项是:(选择1项) A) 子类继承父类,那么子类将继承父类的所有...

    sesvc.exe 阿萨德

    判断当前桶是否为空,空的就需要初始化(resize 中会判断是否进行初始化)。 根据当前 key 的 hashcode 定位到具体的桶中并判断是否为空,为空表明没有 Hash 冲突就直接在当前位置创建一个新桶即可。 如果当前桶有值...

Global site tag (gtag.js) - Google Analytics