国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
java serializable 序列化概述

序列化概述

簡(jiǎn)單來說序列化就是一種用來處理對(duì)象流的機(jī)制,所謂對(duì)象流也就是將對(duì)象的內(nèi)容進(jìn)行流化,流的概念這里不用多說(就是I/O),我們可以對(duì)流化后的對(duì)象進(jìn)行讀寫操作,也可將流化后的對(duì)象傳輸于網(wǎng)絡(luò)之間(注:要想將對(duì)象傳輸于網(wǎng)絡(luò)必須進(jìn)行流化)!在對(duì)對(duì)象流進(jìn)行讀寫操作時(shí)會(huì)引發(fā)一些問題,而序列化機(jī)制正是用來解決這些問題的!

問題的引出:

如上所述,讀寫對(duì)象會(huì)有什么問題呢?比如:我要將對(duì)象寫入一個(gè)磁盤文件而后再將其讀出來會(huì)有什么問題嗎?別急,其中一個(gè)最大的問題就是對(duì)象引用!舉個(gè)例子來說:假如我有兩個(gè)類,分別是A和B,B類中含有一個(gè)指向A類對(duì)象的引用,現(xiàn)在我們對(duì)兩個(gè)類進(jìn)行實(shí)例化{ A a = new A(); B b = new B(); },這時(shí)在內(nèi)存中實(shí)際上分配了兩個(gè)空間,一個(gè)存儲(chǔ)對(duì)象a,一個(gè)存儲(chǔ)對(duì)象b,接下來我們想將它們寫入到磁盤的一個(gè)文件中去,就在寫入文件時(shí)出現(xiàn)了問題!因?yàn)閷?duì)象b包含對(duì)對(duì)象a的引用,所以系統(tǒng)會(huì)自動(dòng)的將a的數(shù)據(jù)復(fù)制一份到b中,這樣的話當(dāng)我們從文件中恢復(fù)對(duì)象時(shí)(也就是重新加載到內(nèi)存中)時(shí),內(nèi)存分配了三個(gè)空間,而對(duì)象a同時(shí)在內(nèi)存中存在兩份,想一想后果吧,如果我想修改對(duì)象a的數(shù)據(jù)的話,那不是還要搜索它的每一份拷貝來達(dá)到對(duì)象數(shù)據(jù)的一致性,這不是我們所希望的!

以下序列化機(jī)制的解決方案:

1.保存到磁盤的所有對(duì)象都獲得一個(gè)序列號(hào)(1, 2, 3等等)

2.當(dāng)要保存一個(gè)對(duì)象時(shí),先檢查該對(duì)象是否被保存了。

3.如果以前保存過,只需寫入"與已經(jīng)保存的具有序列號(hào)x的對(duì)象相同"的標(biāo)記,否則,保存該對(duì)象

通過以上的步驟序列化機(jī)制解決了對(duì)象引用的問題!

序列化的實(shí)現(xiàn)

將需要被序列化的類實(shí)現(xiàn)Serializable接口,該接口沒有需要實(shí)現(xiàn)的方法,implements Serializable只是為了標(biāo)注該對(duì)象是可被序列化的,然后使用一個(gè)輸出流(如:FileOutputStream)來構(gòu)造一個(gè)ObjectOutputStream(對(duì)象流)對(duì)象,接著,使用ObjectOutputStream對(duì)象的writeObject(Object obj)方法就可以將參數(shù)為obj的對(duì)象寫出(即保存其狀態(tài)),要恢復(fù)的話則用輸入流。
package serializable;

import java.io.Serializable;

public class Employee implements Serializable {

 private String name;
 
 private double salary;

 public Employee(String name, double salary) {
  super();
  // TODO Auto-generated constructor stub
  this.name = name;
  this.salary = salary;
 }
 
 public void raiseSalary(double byPercent){
  double temp = salary * byPercent / 100;
  salary += temp;
 }

 public String toString() {
  // TODO Auto-generated method stub
  return getClass().getName() +
   "[ Name = " + name + ", salary = " + salary +"]";
 }

package serializable;

public class Manager extends Employee {
 
 private Employee secretary;

 public Manager(String name, double salary) {
  super(name, salary);
  // TODO Auto-generated constructor stub
  secretary = null;
 }

 public Employee getSecretary() {
  return secretary;
 }

 public void setSecretary(Employee secretary) {
  this.secretary = secretary;
 }

 public String toString() {
  // TODO Auto-generated method stub
  return super.toString() + "[ secretary = " + secretary +"]";
 }
 
}

package serializable;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class Test {
 
 public static void main(String[] args){
  
  Employee employee = new Employee("LiLei", 1000);
  Manager manager1 = new Manager("Jim", 20000);
  manager1.setSecretary(employee);
  
  Employee[] staff = new Employee[2];
  staff[0] = employee;
  staff[1] = manager1;
  
  try{
   ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("employee.dat"));
   oos.writeObject(staff);
   oos.close();
   
   ObjectInputStream ois = new ObjectInputStream(new FileInputStream("employee.dat"));
   Employee[] newStaff = (Employee[])ois.readObject();
   ois.close();
   
   newStaff[0].raiseSalary(1000);
   
   for(int i=0; i<newStaff.length; i++)
    System.out.println(newStaff[i]);
   
  }catch(Exception e)
  {
   e.printStackTrace();
  }
 }
}

修改默認(rèn)的序列化機(jī)制 

 

在序列化的過程中,有些數(shù)據(jù)字段我們不想將其序列化,對(duì)于此類字段我們只需要在定義時(shí)給它加上transient關(guān)鍵字即可,對(duì)于transient字段序列化機(jī)制會(huì)跳過不會(huì)將其寫入文件,當(dāng)然也不可被恢復(fù)。但有時(shí)我們想將某一字段序列化,但它在SDK中的定義卻是不可序列化的類型,這樣的話我們也必須把他標(biāo)注為transient,可是不能寫入又怎么恢復(fù)呢?好在序列化機(jī)制為包含這種特殊問題的類提供了如下的方法定義:

private void readObject(ObjectInputStream in) throws

IOException, ClassNotFoundException;

private void writeObject(ObjectOutputStream out) throws

IOException;

(注:這些方法定義時(shí)必須是私有的,因?yàn)椴恍枰泔@示調(diào)用,序列化機(jī)制會(huì)自動(dòng)調(diào)用的)

使用以上方法我們可以手動(dòng)對(duì)那些你又想序列化又不可以被序列化的數(shù)據(jù)字段進(jìn)行寫出和讀入操作。

下面是一個(gè)典型的例子,java.awt.geom包中的Point2D.Double類就是不可序列化的,因?yàn)樵擃悰]有實(shí)現(xiàn)Serializable接口,在我的例子中將把它當(dāng)作LabeledPoint類中的一個(gè)數(shù)據(jù)字段,并演示如何將其序列化
package transientTest;

import java.awt.geom.Point2D;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;


public class LabeledPoint implements Serializable {

 private String label;
 transient private Point2D.Double point;
 
 public LabeledPoint(String label, double x, double y) {
  super();
  // TODO Auto-generated constructor stub
  this.label = label;
  this.point = new Point2D.Double(x,y);
 }
 
 private void writeObject(ObjectOutputStream oos)throws IOException{
  
  oos.defaultWriteObject();
  oos.writeDouble(point.getX());
  oos.writeDouble(point.getY());
 }
 
 private void readObject(ObjectInputStream ois)throws IOException, ClassNotFoundException{
  
  ois.defaultReadObject();
  double x = ois.readDouble() + 1.0;
  double y = ois.readDouble() + 1.0;
  point = new Point2D.Double(x,y);
 }

 public String toString() {
  // TODO Auto-generated method stub
  return getClass().getName() + "[ Label = " + label + ", point.getX() = "
   + point.getX() + ", point.getY() = " + point.getY() + "]";
 }
}

package transientTest;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class transientTest {

 public static void main(String[] args){
  LabeledPoint label = new LabeledPoint("Book", 5.0, 5.0);
  
  try{
   System.out.println("before:\n" + label);
   
   ObjectOutputStream oos = new ObjectOutputStream(
     new FileOutputStream("c:\\label.txt"));
   oos.writeObject(label);
   oos.close();
   
   System.out.println("after:\n" + label);
   ObjectInputStream ois = new ObjectInputStream(
     new FileInputStream("c:\\label.txt"));
   LabeledPoint label1 = (LabeledPoint)ois.readObject();
   ois.close();
   
   System.out.println("after add 1.0:\n" + label);
  }catch(Exception e)
  {
   e.printStackTrace();
  }
 }
}

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Serializable接口
對(duì)象的序列化與反序列化
序列化和反序列化的底層實(shí)現(xiàn)原理是什么?
Java之Properties及對(duì)象序列化
Java對(duì)象的序列化和反序列化實(shí)踐
JAVA對(duì)象序列化機(jī)制
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服