1、对象序列化
我们平时使用JAVA对象的时候,所有的操作都是在内存中进行的,即对象的生存周期不会比它所依赖的JVM更长。有时候我们又需要即使JVM已经停止,但是有能够在JVM停止后仍然能够获得之前的那些对象,即将这些对象持久化,JAVA对象序列化就能够帮助我们实现这个功能。
JAVA对象序列化能够将对象保存为一组字节,并能够把这些字节在未来还原成对象。这些字节中保存的是对象的状态,即对象的成员变量,这就意味着类的静态对象不会被序列化。
当进行网络传输的时候,RMI,也可以通过序列化传递对象。对于不同语言的平台一般通过XML进行通信。
下面用一个简单示例来了解下对象序列化:
在Java中只要一个类实现了Serializable接口就可以序列化。在这个示例中使用了使用了继承关系,枚举,成员变量是自定义类型。
其中枚举默认继承了java.lang.Enum,这个类实现了Serializable接口
public enum Gender { MALE,FEMALE }
Java要求实现序列化的类的所有成员变量都是可序列化的,即成员变量必须实现Serializable接口
其中People 是主要的测试类,它继承了Human,成员变量中有一个是Race类,都重写了toString()方法,方便打印。
对于序列化的继承关系,稍后再论。这里只要知道,需要序列化的类,其成员变量必须可以序列化,其所有子类都自动实现序列化
public class Race implements Serializable{ private static final long serialVersionUID = 1L; String nation; String race; public Race(String nation, String race) { super(); this.nation = nation; this.race = race; } public Race() { super(); } @Override public String toString() { // TODO Auto-generated method stub return "[nation " +nation+ " | race "+race+"]"; } } public class Human implements Serializable{ float tall; int age; public Human(float tall, int age) { super(); this.tall = tall; this.age = age; } public Human() { super(); } public String toString() { return "[ tall "+tall+" | age "+age+"]"; } } public class People extends Human{ private static final long serialVersionUID = 1L; String name; Race race; Gender gender; public People(float tall, int age, String name, Race race, Gender gender) { super(tall, age); this.name = name; this.race = race; this.gender = gender; } public People() { super(); } @Override public String toString() { // TODO Auto-generated method stub return super.toString()+"[ name "+name+" | gender "+gender+"]"+race; } }
这个是测试类。
public class Main { public static void main(String[] args) throws Exception { Race race=new Race("中国", "汉族"); People people=new People(1.7f, 25, "赵钱孙", race, Gender.MALE); File file=new File("temp"); //将对象持久化到文件中 ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream(file)); oos.writeObject(people); oos.close(); ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file)); Object object=ois.readObject();//没有强制类型转换,需要的话加上 ois.close(); System.out.println(object); People people2=new People(1.8f, 26, "李王陈", race, Gender.MALE); //将字节存储到字节数组中 ByteArrayOutputStream bos =new ByteArrayOutputStream(); ObjectOutputStream oos2=new ObjectOutputStream(bos); oos2.writeObject(people2); oos2.close(); ObjectInputStream ois2=new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray())); Object object2=ois2.readObject(); ois2.close(); System.out.println(object2); } }
输出
[ tall 1.7 | age 25][ name 赵钱孙 | gender MALE][nation 中国 | race 汉族]
[ tall 1.8 | age 26][ name 李王陈 | gender MALE][nation 中国 | race 汉族]
假如Race没有实现Serializable接口,会抛出 java.io.NotSerializableException: Race异常
2、可序列化的范围
为什么一个类实现了Serializable接口,它就可以被序列化呢?在上节的示例中,使用ObjectOutputStream来持久化对象,在该类中有如下代码:
private void writeObject0(Object obj, boolean unshared) throws IOException { ... if (obj instanceof String) { writeString((String) obj, unshared); } else if (cl.isArray()) { writeArray(obj, desc, unshared); } else if (obj instanceof Enum) { writeEnum((Enum) obj, desc, unshared); } else if (obj instanceof Serializable) { writeOrdinaryObject(obj, desc, unshared); } else { if (extendedDebugInfo) { throw new NotSerializableException(cl.getName() + "\n" + debugInfoStack.toString()); } else { throw new NotSerializableException(cl.getName()); } } ... }
从上述代码可知,如果被写对象的类型是String,或数组,或Enum,或Serializable,还有基本类型,那么就可以对该对象进行序列化,否则将抛出NotSerializableException。
原文:http://www.cnblogs.com/maydow/p/4604656.html