Java学习之——Java Serializable
1.什么是Serializable接口?
http://en.wikipedia.org/wiki/Serialization
Java 提供了一种对象序列化的机制,该机制中,一个对象可以被表示为一个字节序列,该字节序列包括该对象的数据、有关对象的类型的信息和存储在对象中数据的类型。
将序列化对象写入文件之后,可以从文件中读取出来,并且对它进行反序列化,也就是说,对象的类型信息、对象的数据,还有对象中的数据类型可以用来在内存中新建对象。
整个过程都是Java虚拟机(JVM)独立的,也就是说,在一个平台上序列化的对象可以在另一个完全不同的平台上反序列化该对象。
类的可序列化通过类实现 java.io.Serializable接口来实现。没有实现这个接口的类将没有序列化或反序列化这两个状态。一个序列化类的子类(subtype)它们自己也是序列化的
。序列化接口没有方法或值,实现它仅仅是为了表示序列化的含义。
2.为什么要有序列化?
StackOverFlow上,有相关问题: http://stackoverflow.com/questions/2232759/what-is-the-purpose-of-serialization-in-java http://stackoverflow.com/questions/441196/why-java-needs-serializable-interface
1.在程序运行过程中,所有的对象都是在内存中。当运行结束时,对象所占的内存被操作系统回收。程序就像是忘记了它运行时发生的所有事一样。序列化正好解决了这个问题,
通过保存对象到磁盘上,因此它可以在下次开始时重新读取。 Java平台允许我们在内存中创建可复用的Java对象,但一般情况下,只有当JVM处于运行时,这些对象才可能存在,即,这些对象的生命周期不会比JVM的生命周期更长。
但在现实应用中,就可能要求在JVM停止运行之后能够保存(持久化)指定的对象,并在将来重新读取被保存的对象。Java对象序列化就能够帮助我们实现该功能。 2.方便传输和持久化:序列化是将对象转化成能被存储的格式(例如文件或内存缓存或在网络连接中传输)。这种机制允许你将对象通过网络进行传播,并可以随时把对象持久化
到数据库、文件等系统里。
3.既然Serializable中没有方法,为什么不将所有类都默认序列化?
为什么不将所有类默认序列化,而必须通过实现Serializable接口来实现Java的序列化机制。 主要有三点原因: 1.不是所有的对象都能在序列化状态中找到有用的语义。例如,一个Thread对象和当前的JVM的状态有关。反序列化的Thread对象没有了保持有用的语义的上下文环境了(Context) 2.对象的序列化状态形成了类相容性的合约。保证不同版本的序列化类的兼容性需要额外的工作和考虑。因此,将一个类变成可序列化类需要深思熟虑的设计的决定,
而不是默认的情况。 3.序列化允许访问非短暂的、私有的类的成员,原本是不能被访问的,包含敏感信息(如密码password)的类不应该被序列化 或 externalizable。
import java.io.Serializable; /** * 实现Serializable接口的类Person * @author lenovo * */ public class Person implements Serializable{ private String name; private int age; private transient int no;//临时的,该属性不会被序列化 public int getNo() { return no; } public void setNo(int no) { this.no = no; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Name:"+this.name+"\nAge:"+this.age+"\nSSN:"+this.no; } }
1 import java.io.FileInputStream; 2 import java.io.FileNotFoundException; 3 import java.io.FileOutputStream; 4 import java.io.IOException; 5 import java.io.ObjectInputStream; 6 import java.io.ObjectOutputStream; 7 8 9 public class Test { 10 public static void main(String[] args) { 11 Person p1 = new Person(); 12 p1.setAge(20); 13 p1.setName("John"); 14 p1.setNo(123456); 15 16 try { 17 FileOutputStream fileOutputStream = new FileOutputStream("C:\\Users\\lenovo\\desktop\\PersonDemo.txt"); 18 ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream); 19 System.out.println("1.序列化:"+p1.getName()); 20 System.out.println(p1.toString()); 21 objectOutputStream.writeObject(p1); 22 objectOutputStream.close(); 23 }catch (FileNotFoundException e) { 24 e.printStackTrace(); 25 }catch (IOException e) { 26 // TODO Auto-generated catch block 27 e.printStackTrace(); 28 } 29 30 try{ 31 FileInputStream fileInputStream = new FileInputStream("C:\\Users\\lenovo\\desktop\\personDemo.txt"); 32 ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream); 33 Person p2 = (Person)objectInputStream.readObject(); 34 System.out.println("2.反序列化:"+p2.getName()); 35 System.out.println(p2.toString()); 36 objectInputStream.close(); 37 }catch(Exception e){ 38 e.printStackTrace(); 39 } 40 41 } 42 }
运行结果:
序列化文件(以16进制保存):