java 序列化之一

1 java序列化基础

   一个类的实例要可以序列化和反序列化,这个类要实现java.io.Serializable 或者 java.io.Externalizable接口,java.io.Serializable只是个标志接口,表示实现该接口的类的时候能被序列化和反序列化。

序列化打印工具类:

/**
 * 序列化工具类
 * @author hehaibo
 *
 */
public class SerialUtils {
	/**
	 * 将序列化对象写入到文件中
	 * 
	 * @param object
	 *            对象
	 * @param fileName
	 *            文件名
	 * @throws IOException
	 * @throws FileNotFoundException
	 */
	public static void writeObject(Object object, String fileName)
			throws IOException {
		FileOutputStream fos =  new FileOutputStream(new File(fileName));
		ObjectOutputStream oos = new ObjectOutputStream(
				new FileOutputStream(new File(fileName)));
		oos.writeObject(object);
		oos.flush();
		oos.close();
		fos.close();
		Printer.printf(fileName);
	}
	
	/**
	 * 反序列化一个对象
	 * @param fileName
	 * @return
	 * @throws IOException
	 * @throws ClassNotFoundException
	 */
	public static Object readObject(String fileName) throws IOException, ClassNotFoundException{
		Object obj = null;
		FileInputStream fis = new FileInputStream(new File(fileName));
		ObjectInputStream ois = new ObjectInputStream(fis);
		obj = ois.readObject();
		ois.close();
		fis.close();
		return obj;
	}
}

 

public class Printer {
	public static  int length=16 ;
	
	public static void registerLength(int len){
		length=len;
	}
	public static void printf(String fileName) throws IOException {
		File file = new File(fileName);
		System.out.println("文件大小:" + file.length());
		InputStream fis;
		fis = new FileInputStream(file);
		byte bs[] = new byte[length];
		while ((length = fis.read(bs)) != -1) {
			System.out.print(Binary2Hex.Bytes2HexString(bs, length) + "\r");
		}
		fis.close();
	}
}

 

/**
 * 二进制转化为十六进制
 * 
 * @author wb_haibo.hehb
 */
public class Binary2Hex {
	/**
	 * 
	 * @param b
	 *            byte[]
	 * @return String
	 */
	public static String Bytes2HexString(byte[] b, int length) {
		String ret = "";
		// int ia=0xFF;
		// System.out.println(Integer.toBinaryString(ia));
		for (int i = 0; i < length; i++) {
			// System.out.println(Integer.toBinaryString(b[i]));
			String hex = Integer.toHexString(b[i] & 0xFF);
			// if (hex.length() == 2) {
			hex = "0x" + hex.toUpperCase();
			// }
			if (hex.length() == 3) {
				hex = hex + " ";
			}
			ret += hex + " ";
		}
		return ret;
	}
}

 

  序列化示例:

  

public interface SuperInterface {
	public static final String abc="abc";
}

 

 

public class Person implements Serializable,SuperInterface {
	public static final String staVal="staVal";
	private String name;
	private String account;
	private String password;
	transient private String sex;
	public Person(){
		System.out.println("son come!");
	}
}

 

/**
 * 无继承extentds场景 
 * 1 增加方法-->方法不会被序列化,因为方法可以通过类的字节码获得。
 * 2 增加静态变量-->静态变量不会被序列化,静态变量属于类级别的变量,和类的实例无关 
 * 3 增加transient[瞬态]的成员变量-->不会被序列化 
 * 4 增加普通属性--> 会被写入序列化中。 
 * 5 类实现自定义的接口 [含有公共变量]-->接口中的变量不会被序列化。
 * @author hehaibo
 */
public class TestCaseOne {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		try {
			SerialUtils.writeObject(new Person(), "hehaibo");
			Object object = SerialUtils.readObject("hehaibo");
			System.out.println(object);
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}
}

   输出结果:

 

son come!
文件大小:104
0xAC 0xED 0x0  0x5  0x73 0x72 0x0  0x15 0x6F 0x72 0x67 0x2E 0x68 0x68 0x62 0x2E 
0x73 0x65 0x72 0x69 0x61 0x6C 0x2E 0x50 0x65 0x72 0x73 0x6F 0x6E 0x62 0x4D 0x55 
0x76 0x9B 0xA8 0x3  0xBD 0x2  0x0  0x3  0x4C 0x0  0x7  0x61 0x63 0x63 0x6F 0x75 
0x6E 0x74 0x74 0x0  0x12 0x4C 0x6A 0x61 0x76 0x61 0x2F 0x6C 0x61 0x6E 0x67 0x2F 
0x53 0x74 0x72 0x69 0x6E 0x67 0x3B 0x4C 0x0  0x4  0x6E 0x61 0x6D 0x65 0x71 0x0  
0x7E 0x0  0x1  0x4C 0x0  0x8  0x70 0x61 0x73 0x73 0x77 0x6F 0x72 0x64 0x71 0x0  
0x7E 0x0  0x1  0x78 0x70 0x70 0x70 0x70 
org.hhb.serial.Person@1df073d

 

 

    序列化的子类继承示例:

   

public class Person 
extends SuperClasss 
implements Serializable{
	public static final String staVal="staVal";
	private String name;
	private String account;
	private String password;
	transient private String sex;
	public Person(){
//		super("abc");
		System.out.println("son come!");
	}
	
}
public class SuperClasss implements Serializable,SuperInterface{
	private String test="test";
	public SuperClasss(){
		System.out.println("old father come 1!");
	}
//	public SuperClasss(String name){
//		System.out.println("old father come 2!");
//	}
}

  

/**
 * 场景:
 * 1 序列化的子类继承不实现序列化的父类<br>
 *   1.1 子类提供默认的构造函数,父类提供默认构造函数<br>
 *  	 序列化时会调用父类的默认构造函数,父类的普通域不会被序列化<br>
 *  
 *  	原因分析:
 *  	
 *  	反序列化时:会调用父类默认的构造函数。
 *  
 * 	 1.2 子类提供默认的构造函数,父类提供非默认的构造函数,子类未调用父类被覆盖的构造函数<br>
 * 	  	编译错误,提示要调用父类的构造函数,这也是java的基础,构造函数隐含super()<br>
 * 	 
 * 	 1.3 子类提供默认的构造函数,父类提供非默认的构造函数,子类的构造函数中调用父类被覆盖的构造函数<br>
 * 		 运行时错误, java.io.InvalidClassException: org.hhb.serial.Person; org.hhb.serial.Person; no valid constructor<br> 
 *   
 *   	原因分析:
 *   	
 *   1.4 子类提供默认的构造函数,父类的提供默认构造函数,也提供其他构造函数<br>
 *   	序列化时会只调用父类的默认构造函数,父类的普通域不会被序列化<br>
 *    
 *    	反序列化时:同1.1,会调用父类默认的构造函数。
 *   
 *  2  序列化的子类继承实现序列化的父类<br> 
 *  	
 *	   	序列化时不会调用 父类的构造函数,父类的普通域会写入序列化
 *		反序列化时,也不会调用父类的构造函数,也不会调用子类的构造函数
 *		原因分析:
 *
 */
public class TestCaseTwo {

	/**
	 * @param args
	 * @throws IOException 
	 * @throws ClassNotFoundException 
	 */
	public static void main(String[] args) throws IOException, ClassNotFoundException {
		
		SerialUtils.writeObject(new Person(), "zhangsan");
		Object o = SerialUtils.readObject("zhangsan");
		System.out.println(o);
		SerialUtils.readObject("zhangsan");
	}
}

 

 

  待续...

  Externalizable继承 Serializable接口,增加了2个方法.

public interface Externalizable extends java.io.Serializable {
    void writeExternal(ObjectOutput out) throws IOException;
    void readExternal(ObjectInput in) throws IOException, ClassNotFoundException;
}

 

你可能感兴趣的:(java)