java序列化

今天有同事问我动态读写对象的问题,于是就想到了序列化。在此做下笔记,防止丢失被盗

 



 

 

package org.vic.test.model;

import java.io.Serializable;
import java.util.List;

public class Class  implements Serializable{
	
	/**
	 * 
	 */
	private static final long serialVersionUID = -4684355891224377925L;

	private String name;
	
	private List<Stu> students;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public List<Stu> getStudents() {
		return students;
	}

	public void setStudents(List<Stu> students) {
		this.students = students;
	}
	
}

 

 

package org.vic.test.model;

import java.io.Serializable;
import java.util.List;

public class Grade implements Serializable {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = -3162228744230892998L;

	private String name;
	
	private List<Class> classes;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public List<Class> getClasses() {
		return classes;
	}

	public void setClasses(List<Class> classes) {
		this.classes = classes;
	}
	
}

 

package org.vic.test.model;

import java.io.Serializable;

public class Stu  implements Serializable{
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 3175234590284653474L;

	private String id;
	
	private String name;
	
	private int age;

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	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;
	}
	
}

 

package org.vic.test.tester;

import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;

import org.vic.test.model.Grade;
import org.vic.test.model.Stu;

public class MyTester {

	private static final String path = "d:\\test.obj";

	public static void main(String[] args) throws FileNotFoundException,
			IOException, ClassNotFoundException {
		 Stu s0= new Stu();
		 s0.setId("1");
		 s0.setName("zhangsan");
		 s0.setAge(12);
		
		 Stu s1= new Stu();
		 s1.setId("2");
		 s1.setName("lisi");
		 s1.setAge(13);
		
		 Stu s2= new Stu();
		 s2.setId("3");
		 s2.setName("wangwu");
		 s2.setAge(14);
		
		
		 List<Stu> list = new ArrayList<>();
		 list.add(s0);
		 list.add(s1);
		 list.add(s2);
		
		 org.vic.test.model.Class c = new org.vic.test.model.Class();
		 c.setStudents(list);
		 c.setName("class 1");
		 List<org.vic.test.model.Class> classList = new ArrayList<>();
		 classList.add(c);
		
		
		
		 Grade g = new Grade();
		 g.setName("grade 5");
		 g.setClasses(classList);
		 
		 
		 write(g,null);

//		Grade g = read("");
//		String grade_name = g.getName();
//		System.out.println(grade_name);
//		List<org.vic.test.model.Class> classes = g.getClasses();
//		for (org.vic.test.model.Class c : classes) {
//			String class_name = c.getName();
//			System.out.println(class_name);
//			List<Stu> students = c.getStudents();
//			for (Stu s : students) {
//				int age = s.getAge();
//				String id = s.getId();
//				String name = s.getName();
//				System.out
//						.println("name=" + name + " age=" + age + " id=" + id);
//			}
//		}

	}

	public static void write(Grade g, String userPath)
			throws FileNotFoundException, IOException {
		File file;
		if (userPath == null || "".equals(userPath.trim())) {
			file = new File(path);
		} else {
			file = new File(userPath);
		}
		if (!file.exists()) {
			file.createNewFile();
		}
		FileOutputStream fOut = new FileOutputStream(file);
		ObjectOutputStream out = new ObjectOutputStream(fOut);
		out.writeObject(g);
		out.flush();
		closeStreams(out);
	}

	public static Grade read(String userPath) throws IOException,
			ClassNotFoundException {
		File file;
		if (userPath == null || "".equals(userPath.trim())) {
			file = new File(path);
		} else {
			file = new File(userPath);
		}
		FileInputStream fIn = new FileInputStream(file);
		ObjectInputStream in = new ObjectInputStream(fIn);
		Grade g = (Grade) in.readObject();
		return g;
	}

	public static void closeStreams(Closeable... streams) throws IOException {
		if (streams != null) {
			for (Closeable c : streams) {
				if (c != null) {
					c.close();
				}
			}
		}
	}
}

 

### 序列化的含义 序列化指将堆内存中的 Java 对象数据,通过某种方式存储到磁盘文件中,或者传递给其他网络节点(网络传输),即将对象转化为二进制,用于保存或网络传输。反序列化则是从 IO 流中恢复对象[^1][^4]。 ### 序列化的意义 序列化机制允许将实现序列化Java 对象转换为字节序列,这些字节序列可以保存在磁盘上,或通过网络传输,以达到以后恢复成原来的对象。序列化机制使得对象可以脱离程序的运行而独立存在[^1]。 ### 序列化的使用场景 所有可在网络上传输的对象都必须是可序列化的,比如 RMI(remote method invoke,即远程方法调用),传入的参数或返回的对象都是可序列化的,否则会出错;所有需要保存到磁盘的 Java 对象都必须是可序列化的。通常建议程序创建的每个 JavaBean 类都实现 Serializable 接口[^1]。 ### 序列化实现的方式 #### Serializable 接口 - **普通序列化**:实现 Serializable 接口后,可使用 ObjectOutputStream 将对象写入流,使用 ObjectInputStream 从流中读取对象。 ```java import java.io.*; class Person implements Serializable { String name; int age; public Person(String name, int age) { this.name = name; this.age = age; } } public class SerializationExample { public static void main(String[] args) { Person person = new Person("John", 30); try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.ser"))) { oos.writeObject(person); } catch (IOException e) { e.printStackTrace(); } try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.ser"))) { Person deserializedPerson = (Person) ois.readObject(); System.out.println(deserializedPerson.name + " " + deserializedPerson.age); } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); } } } ``` - **成员是引用的序列化**:若类的成员是引用类型,该引用类型也必须是可序列化的,否则当前类无法实现序列化。 - **同一对象序列化多次的机制**:Java 序列化算法会保证同一对象多次序列化时,不会重复序列化对象的内容,而是只记录对象的引用。 - **Java 序列化算法潜在的问题**:例如序列化版本号不匹配、性能问题等。 - **可选的自定义序列化**:可通过实现 `writeObject` 和 `readObject` 方法来自定义序列化和反序列化过程。 #### Externalizable 接口 Externalizable 接口强制自定义序列化,需要实现 `writeExternal` 和 `readExternal` 方法。 ```java import java.io.*; class Employee implements Externalizable { String name; int id; public Employee() {} public Employee(String name, int id) { this.name = name; this.id = id; } @Override public void writeExternal(ObjectOutput out) throws IOException { out.writeObject(name); out.writeInt(id); } @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { name = (String) in.readObject(); id = in.readInt(); } } ``` ### 序列化版本号 serialVersionUID serialVersionUID 用于确保序列化和反序列化时类的版本一致性。若没有显式定义 serialVersionUID,Java 会根据类的结构自动生成一个。当类的结构发生变化时,可能会导致 serialVersionUID 改变,从而在反序列化时抛出 `InvalidClassException`。建议显式定义 serialVersionUID。 ```java import java.io.Serializable; class MyClass implements Serializable { private static final long serialVersionUID = 1L; // 类的成员和方法 } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值