Java对象序列化存储实现

在java中要将某个对象持久化 即写入文件当中要实现java.io.Serializable接口 该接口没有任何方法如果不实现该接口当你从从文件读取时会通过构造器新构造一个对象 而并非去读取
transient这是一个相对冷门的关键字
用这个关键字修饰的属性在序列化存储时将不被存储。
要实现部分序列华存储还有另一个办法就是实现java.io.Externalizable该接口有两个方法
void readExternal(ObjectInput in)
void writeExternal(ObjectOutput out)
当你调用这个in.writeObject()写入这个类时会调用到这个void writeExternal(ObjectOutput out)方法同样在读取时会调用void readExternal(ObjectInput in) 方法
再介绍一下ObjecInputStream
该类有一个readObject方法可以读写非基本类型的属性
通过一个FileinputStream构造
package com.inky.thinking.chapter1;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Collection;

import junit.framework.TestCase;
/**
 * 该类实现接口Serializable 因此可以序列化存储到硬盘
 * 如果没有实现该接口则在从文件读取时会通过构造器构造而不是读取
 * @author inky
 *两个属性 name addr 其中addr被transient修饰
 */
class MyClass implements java.io.Serializable{
	public String name;
	/**
	 * transient修饰
	 */
	transient public String addr;
	
	public MyClass(int x){
		name = "this is name for "+x;
		addr = "this is addr for "+x;
		System.out.println("构造函数被调用");
	}
	public String toString(){
		return "name:\t"+name+"\naddr:\t"+addr;
	}
	
}
/**
 * 在上一个基础上实现了java.io.Externalizable接口
 * 该接口有两个方法readExternal writeExternal
 * @author inky
 *
 */
class MyClass2 implements java.io.Serializable,java.io.Externalizable{
	public String name;
	/**
	 * 这里没有修饰
	 */
	public String addr;
	public MyClass2(){
		System.out.println("无参构造函数被调用!");
	}
	public MyClass2(int x){
		name = "this is name for "+x;
		addr = "this is addr for "+x;
		System.out.println("构造函数被调用");
	}
	public String toString(){
		return "name:\t"+name+"\naddr:\t"+addr;
	}
	
	public void readExternal(ObjectInput in) throws IOException,
			ClassNotFoundException {
		name = (String)in.readObject();
		//addr = (String)in.readObject();
		System.out.println("readExternal被调用!");
	}
	
	public void writeExternal(ObjectOutput out) throws IOException {
		out.writeObject(name);
		//out.writeObject(addr);
		System.out.println("writeExternal被调用!");
	}
	
}

public class JavaString {
	
	public static void main(String args[]) throws FileNotFoundException, IOException, ClassNotFoundException{
	
		File f= new File("logInfo.out");
		f.createNewFile();
		MyClass mc1 = new MyClass(1);
		MyClass mc2 = new MyClass(2);
		MyClass2 mc3 = new MyClass2(3);
		MyClass2 mc4 = new MyClass2(4);
		
		ObjectOutputStream o = new ObjectOutputStream(new FileOutputStream(f));
		//依次写入三个对象
		o.writeObject(mc1);
		mc3.writeExternal(o);
		o.writeObject(mc4);
		o.close();
		
		
		
		ObjectInputStream in = new ObjectInputStream(new FileInputStream(f));
		System.out.println(mc1);
		mc2 = (MyClass)in.readObject();
		System.out.println(mc2);
		
		
		mc3.readExternal(in);
		System.out.println(mc3);
		
		mc4 = (MyClass2)in.readObject();
		System.out.println(mc4);
		
		in.close();
	}
}

结果
引用
构造函数被调用
构造函数被调用
构造函数被调用
构造函数被调用
writeExternal被调用!   //直接调用
writeExternal被调用!   //writeObject时调用
name: this is name for 1
addr: this is addr for 1
name: this is name for 1
addr: null
readExternal被调用!
name: this is name for 3
addr: this is addr for 3 //这里是修改 所以指保留原来
无参构造函数被调用!
readExternal被调用!
name: this is name for 4
addr: null               //这里是空直 没有transient修饰也可以实现

你可能感兴趣的:(java,JUnit,F#)