java object对象序列化_java ObjectInputStream/OutputStream(对象序列化与反序列化)

ObjectOutputStream(对象的输出流类) : 该类主要是用于把对象数据写出到文件上的。

ObjectInputStream(对象的输入流类 ) : 把硬盘中的对象数据读取回来。

对象的输入输出流要注意的实现:

使用ObjectOutputStream的writeObject方法时候,只能写出实现了Serializable接口的对象。Serializable 接口没有任何的方法,这种接口我们称作为标识接口。

对象反序列化的时候创建对象是不会调用构造方法的。

我们把对象写到文件上的时候,文件除了记录对象的一些信息以外,还记录了class的版本号(serialVersionUID), 这个版本号是通过一个类的类名、 包名、 工程名、成员一起算出的一个id号。

在反序列化的时候,jvm会使用本地class文件算出一个id号与文件记录的id号进行对比,如果不一致,反序列化失败。

如果一个类的成员可能在后期会发生改动,那么可以在序列化之前就指定一个serialVersionUID , 如果一个类一家指定了一个serialVersionUID那么java虚拟机则不会再计算该class文件的serialVersionUID了。

如果一个类的某些成员不想被序列化到硬盘上,可以使用关键字transient修饰。 static修改的成员也不会被序列化到

如果一个类的内部维护了另外一个类对象,那么另外一个类也必须 要实现Serializable接口。

//地址类

class Address implements Serializable{

String country;

String city;

public Address(String country, String city) {

super();

this.country = country;

this.city = city;

}

}

//用户类

class User implements Serializable{

private static final long serialVersionUID = 1L;

Address address = new Address("中国","广州");

String userName;

int password;

transient int age; // transient 透明

public User(String userName, int password, int age) {

this.userName = userName;

this.password = password;

this.age =age;

}

@Override

public String toString() {

return "用户名:"+this.userName+" 密码:"+ this.password+" 年龄:"+ this.age;

}

}

public class Demo3 {

public static void main(String[] args) throws Exception {

writeObj();

// readObj();

}

//对象的反序列化-----> 读取硬盘中的对象到内存中。

public static void readObj() throws Exception{

//找到目标文件

File file = new File("f:\\obj.txt");

//建立数据的输入流对象

FileInputStream fileInputStream = new FileInputStream(file);

//建立对象的输入流

ObjectInputStream inputStream = new ObjectInputStream(fileInputStream);

//读取对象的数据

User user = (User) inputStream.readObject(); //反序列化的时候需要创建对象, 创建对象需要依赖什么? Class文件

System.out.println("对象的信息:"+ user);

}

//把对象写到文件上------>对象的序列化。

public static void writeObj() throws IOException{

User user = new User("admin",123,18);

//找到目标

File file = new File("f:\\obj.txt");

//建立数据的输出通道

FileOutputStream fileOutputStream = new FileOutputStream(file);

//建立对象的输出流对象

ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);

//把对象写出到输出流中

objectOutputStream.writeObject(user);

//关闭资源

objectOutputStream.close();

}

}

练习:

使用ObjectInputStream/OutputStream类重新实现登录注册功能

import java.io.*;

import java.util.HashSet;

import java.util.Scanner;

class User implements Serializable{

private final long serialVersionUID = 1L;

String name;

String passwd;

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public String getPasswd() {

return passwd;

}

public void setPasswd(String passwd) {

this.passwd = passwd;

}

public User(String name,String passwd){

this.name = name;

this.passwd = passwd;

}

@Override

public int hashCode() {

return this.name.hashCode();

}

@Override

public boolean equals(Object obj) {

User user = (User)obj;

return (user.name.equals(this.name));

}

}

public class Demo01 {

static HashSet set = new HashSet ();

static File userFile = new File("C:/Users/Administrator/Desktop/register");

public static void main(String[] args) throws IOException, ClassNotFoundException {

readFromFile();

while(true){

System.out.println("请选择功能");

System.out.println("1.登录 2.注册 3.退出");

int sel = new Scanner(System.in).nextInt();

switch(sel){

case 1:

login();

break;

case 2:

register();

break;

case 3:

exit();

break;

default:

System.out.println("没有改该选项,请重新选择");

break;

}

}

}

/**

* 登录*/

public static void login(){

System.out.println("用户名:");

String name = new Scanner(System.in).nextLine();

System.out.println("密码:");

String passwd = new Scanner(System.in).nextLine();

for(User user :set){

if(user.getName().equals(name) ){

if(user.getPasswd().equals(passwd)){

System.out.println("登录成功");

return;

}

else{

System.out.println("密码错误");

return;

}

}

}

System.out.println("用户不存在");

}

/**

* 注册*/

public static void register (){

while(true){

System.out.println("请输入以下信息:");

System.out.println("用户名:");

String name = new Scanner(System.in).nextLine();

System.out.println("密码:");

String passwd = new Scanner(System.in).nextLine();

if(set.add(new User(name,passwd))){

System.out.println("注册成功");

break;

}else{

System.out.println("用户名已存在");

}

}

}

/**

* 从文件中读取数据

* @throws ClassNotFoundException */

public static void readFromFile() throws IOException, ClassNotFoundException{

if(!userFile.exists()){

userFile.createNewFile();

}else{

FileInputStream FileIStream= new FileInputStream(userFile);

ObjectInputStream objIStream = new ObjectInputStream(FileIStream);

set = (HashSet) objIStream.readObject();

System.out.println(set.size());

objIStream.close();

}

}

/**

* 退出程序*/

public static void exit() throws IOException {

if(!userFile.exists()){

userFile.createNewFile();

}

FileOutputStream outStream = new FileOutputStream(userFile);

ObjectOutputStream objOutStream = new ObjectOutputStream(outStream);

objOutStream.writeObject(set);

objOutStream.close();

System.out.println("已退出");

System.exit(0);

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java序列是将对象转换为字节流的过程,而序列则是将字节流转换回对象的过程。下面是Java序列序列的基本过程: 1. 实现Serializable接口:要使一个类可序列,需要实现Serializable接口。这是一个标记接口,表示该类可以被序列。 2. 创建输出流:使用输出流将对象序列为字节流。常用的输出流有ObjectOutputStream和其他实现了OutputStream接口的类。 3. 将对象写入输出流:使用输出流的writeObject()方法将对象写入输出流。对象会被转换为字节序列并写入输出流。 4. 创建输入流:使用输入流将字节流序列对象。常用的输入流有ObjectInputStream和其他实现了InputStream接口的类。 5. 从输入流读取对象:使用输入流的readObject()方法从输入流中读取字节序列,并将其转换为对象。 6. 关闭流和处理异常:在序列序列过程中,应该适当地关闭流,并处理相关的异常。 需要注意的是,被序列的类必须具有默认构造函数,并且其非序列的成员变量需要使用transient关键字进行标记,以避免被序列。 以下是一个简单的示例代码,演示了Java序列序列的过程: ```java import java.io.*; public class SerializationExample { public static void main(String[] args) { // 序列对象 try { // 创建输出流 FileOutputStream fileOut = new FileOutputStream("data.ser"); ObjectOutputStream out = new ObjectOutputStream(fileOut); // 创建对象 MyClass obj = new MyClass("John", 25); // 写入对象到输出流 out.writeObject(obj); // 关闭流 out.close(); fileOut.close(); System.out.println("对象序列为字节流"); } catch (IOException e) { e.printStackTrace(); } // 序列对象 try { // 创建输入流 FileInputStream fileIn = new FileInputStream("data.ser"); ObjectInputStream in = new ObjectInputStream(fileIn); // 从输入流读取对象 MyClass obj = (MyClass) in.readObject(); // 关闭流 in.close(); fileIn.close(); // 输出对象的属性 System.out.println("姓名:" + obj.getName()); System.out.println("年龄:" + obj.getAge()); } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); } } } // 要进行序列的类,实现Serializable接口 class MyClass implements Serializable { private static final long serialVersionUID = 1L; private String name; private transient int age; // 使用transient关键字标记不需要序列的成员变量 public MyClass(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public int getAge() { return age; } } ``` 这就是Java序列序列的基本过程。通过序列序列,可以在网络传输、持久存储等场景中方便地传递和存储对象

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值