通常情况下,用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);
}
分享到:
相关推荐
修饰变量 方法 静态块(初始化块 构造函数 ) 静态内部类() 静态导包 final() transient() foreach循环原理() volatile底层实现() equals和hashcode(, ) string,stringbuffer和stringbuilder(,,,, ) 伪泛型(, , ) 自动...
上章讲了访问控制符,这章开始讲非访问控制符。 java中的非访问修饰符的作用各不一样,据我所知常用的有六种: static final abstract synchronized volatile ...被static修饰的方法我们称为静态方
成员变量的声明格式: [<修饰符>] [static] [final] [transient] <变量类型> <变量名> static: 表示是一个类成员变量(静态变量); final: 表示是一个常量; (最终成员变量) 例:final double PI=3.1415926; ...
创建对象包括声明、实例化和初始化三方面的内容。通常的格式为 : 1. 声明对象 对象声明实际上是给对象命名,也称定义一个实例变量。对象声明的一般格式为: type name 其中,type 是一个类的类名,用它声明的对象将...
•局部内部类不能在外部类以外的地方使用,那么局部内部类也不能使用访问控制符和static修饰 匿名内部类 •匿名内部类适合创建那种只需要一次使用的类,定义匿名内部类的语法格式如下: •new 父类构造器...
protected,final,throw,super,synchronized,static,finally,abstract,transient,instanceof 答:protected`: `protected` 是 Java 中的一种访问修饰符,它用于指定一个成员变量或方法 可以被同一包内的类和所有子类...
知识回顾 修饰符: 权限修饰符:public、 protected、默认不写、private public:共有的、当前工程的任意位置都能... 修饰变量:只有一次赋值的机会、赋值之后值不能发生改变 属性:要求必须赋初始值、不能
Q0043 java相关概念 "static:静态,无需实例化,可直接引用,全局只有一份copy,修饰变量和方法 final:最终的,不可继承、不可修改,修饰变量、方法、类 volatile:volatile变量表示保证它必须是与主内存保持一致,...
C) 程序能通过编译,运行时将打印出0/0,因为在Java中int型变量day和month默认为0。 D) 以上说法都不正确。 题目10:c 下面关于继承的描述正确的一项是:(选择1项) A) 子类继承父类,那么子类将继承父类的所有...
判断当前桶是否为空,空的就需要初始化(resize 中会判断是否进行初始化)。 根据当前 key 的 hashcode 定位到具体的桶中并判断是否为空,为空表明没有 Hash 冲突就直接在当前位置创建一个新桶即可。 如果当前桶有值...