Serializable(一)--初步理解

来源:互联网 发布:夜神模拟器清理数据 编辑:程序博客网 时间:2024/06/15 10:36
Serializable(一)--初步理解   
       一 序列化是干什么的?
       

我们知道,在jvm中引用数据类型存在于栈中,而new创建出的对象存在于堆中。如果电脑断电那么存在于内存中的对象就会丢失。那么有没有方法将对象保存到磁盘(对象持久化存储)或通过网络传输到远处的其他地方呢?

答案是可以,但是我们必须要求所有支持持久化存储的类实现Serializable接口。Serializable就像个通行证,只有持有这个通行证,jvm才让类创建的对象进行持久化。这个接口将类与一个称为serialVersionUID的变量关联起来,这个serialVersionUID就是在反序列化中用来确定由哪个类来加载这个对象。


      二、什么情况下需要序列化   
    a)当你想把的内存中的对象状态保存到一个文件中或者数据库中时候;
    b)当你想用套接字在网络上传送对象的时候;
    c)当你想通过RMI传输对象的时候;

 

        三、JavaBean为什么要实现java.io.Serializable接口实现序列化?

       找了个比较好理解的例子:客户端访问了某个能开启会话功能的资源, web服务器就会创建一个与该客户端对应的HttpSession对象,每个HttpSession对象都要站用一定的内存空间。如果在某一时间段内访问站点的用户很多,web服务器内存中就会积累大量的HttpSession对象,消耗大量的服务器内存,即使用户已经离开或者关闭了浏览器,web服务器仍要保留与之对应的HttpSession对象,在他们超时之前,一直占用web服务器内存资源。

web服务器通常将那些暂时不活动但未超时的HttpSession对象转移到文件系统或数据库中保存,服务器要使用他们时再将他们从文件系统或数据库中装载入内存,这种技术称为Session的持久化。

将HttpSession对象保存到文件系统或数据库中,需要采用序列化的方式将HttpSession对象中的每个属性对象保存到文件系统或数据库中;将HttpSession对象从文件系统或数据库中装载如内存时,需要采用反序列化的方式,恢复HttpSession对象中的每个属性对象。所以存储在HttpSession对象中的每个属性对象必须实现Serializable接口。当然如果不是存储在session中的JavaBean可以不用存储哈。

   

     举个简单例子:

     Student

import java.io.Serializable;public class Student implements Serializable {/*serialVersionUID来决定由哪个类来加载存在于文件中的对象     * 如果指定serialVersionUID的数值,那就能使得其不再与类的成员变量相关联     * 不然你已经把对象保存到数据库,这个时候你再给这个对象新增属性,那么反序列化     * 就会报:本地类不匹配的错误,但如果指定serialVersionUID值那就不会报错。     */ private static final long serialVersionUID = -5182532647273106745L;  //成员变量写成static的话是不能被持久化的  public static  String countryName="china";        private String name;          private int age;          //如果想对非静态的数据也不想序列化,则需要加入关键字         transient String sex;        /* 提供set和get方法,无参和有参方法*/}
        测试类

import java.io.*;public class SerializableTest {public static void main(String[] args) {          writeObj();          readObj();      }      public static  void writeObj()      {          Student student=new Student("小筱", 1, "女");             try {              ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("d:\\student.txt"));              oos.writeObject(student);              oos.close();          } catch (IOException e) {              e.printStackTrace();          }      }      public  static  void  readObj()      {          try {              ObjectInputStream ooi=new ObjectInputStream(new FileInputStream("d:\\student.txt"));              try {                  Object obj=ooi.readObject();                  Student student=(Student)obj;                   System.out.println("age:"+student.getAge()+",name:"+student.getName()+",countryName:"+student.countryName+",sex:"+student.getSex());              } catch (ClassNotFoundException e) {                  e.printStackTrace();              }              ooi.close();          } catch (IOException e) {              e.printStackTrace();          }      }  }
后台输出:我们会发现sex是没有值的,因为被transient。



再看student.txt文档是什么。



 第二个小例子我没有亲自测试用套接字在网络上传送对象

   1.首先建立要传输的对象  

/建立用来持续化的对象  import java.io.Serializable;  public class ObjectSeri implements Serializable{            //成员变量写成static的话是不能被持久化的      //private关键字是不能被持久化的,脱离了JVM,成员变量是不在JVM的安全机制之内      private String name;      private String age;      /*set和get方法*/    
2.有了传输的对象,下一步就是建立一个服务端线程来监听socket端口,并且在run方法里面实现读取对象的数据
import java.io.IOException;      import java.io.ObjectInputStream;      import java.net.ServerSocket;      import java.net.Socket;    //serverTest类继承thread类,监听端口来的信息  public class serverTest extends Thread {  //  private final String serverIP = "127.0.0.1";      private final int serverPort = 3400;      private ServerSocket server;      public serverTest() {          try {              // ServerSocket server=new ServerSocket(serverPort);              server = new ServerSocket(serverPort);              System.out.println("正在监听3400端口");          } catch (IOException e) {              e.printStackTrace();          }      }      public void run() {          Socket socket = null;          ObjectInputStream in;          while (true) {              try {                  synchronized (server) {                      socket = server.accept();                  }                  System.out.println("当前的连接是:"                          + socket.getInetAddress().toString());                  socket.setSoTimeout(20000);                  in = new ObjectInputStream(socket.getInputStream());                  ObjectSeri data = (ObjectSeri) in.readObject();                  System.out.println("The name is:" + data.getName()                          + "and age is:" + data.getAge());                  in.close();                  in = null;                  socket.close();              } catch (IOException | ClassNotFoundException e) {                  e.printStackTrace();              }          }      }         public static void main(String args[]) {            (new serverTest()).start();           }  
3.最后,建立一个客户端来测试下
import java.io.ObjectOutputStream;      import java.net.InetSocketAddress;      import java.net.Socket;   //建立一个client测试类  public class TestClient {      private String address = "127.0.0.1";      private int port = 3400;        public TestClient() {          // Prepare the data need to transmit          ObjectSeri data = new ObjectSeri();          data.setName("Scott");          data.setAge("34");          Socket client = new Socket();          InetSocketAddress adr = new InetSocketAddress(this.address, this.port);          try {              client.connect(adr, 10000);              ObjectOutputStream out = new ObjectOutputStream(                      client.getOutputStream());              // send object              out.writeObject(data);              out.flush();              out.close();              out = null;              data = null;              client.close();              client = null;          } catch (java.io.IOException e) {                System.out.println("IOException :" + e.toString());          }      }      public static void main(String[] args) {          new TestClient();       }    }  
输出结果如下:

正在监听3400端口
当前的连接是:/127.0.0.1
The name is:Scottand age is:34


今天:2017:12:05 发现自己用到了,就是jquery表单提交,用post提交,这样有个最大的好处,就是我不用一个值一个值提交,而是把表单提交过去        
$.post('your url', $("form").serialize(), function(data) {        // your code    }});


水滴石穿,成功的速度一定要超过父母老去的速度! 少尉【2】