什么是java序列化,如何实现java序列化? .

本文详细介绍了Java串行化技术的原理、用途、序列化的实现方式以及特点,包括如何将对象的状态写入和从Byte流中读出对象,以及序列化的主要类和接口。此外,还通过示例代码展示了如何实现对象的序列化和反序列化。

Java 串行化技术可以使你将一个对象的状态写入一个Byte 里,并且可以从其它地方把该Byte 流里的数据读出来,重新构造一个相同的对象。这种机制允许你将对象通过网络进行传播,并可以随时把对象持久化到数据库、文件等系统里Java的串行化机制是RMIEJB等技术的技术基础。用途:利用对象的串行化实现保存应用程序的当前工作状态,下次再启动的时候将自动地恢复到上次执行的状态。

序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。序列化是为了解决在对对象流进行读写操作时所引发的问题。

序列化的实现:将需要被序列化的类实现Serializable接口,然后使用一个输出流(如:FileOutputStream)来构造一个ObjectOutputStream(对象流)对象,接着,使用ObjectOutputStream对象的writeObject(Object obj)方法就可以将参数为obj的对象写出(即保存其状态),要恢复的话则用输入流。

2、串行化的特点:

    1)如果某个类能够被串行化,其子类也可以被串行化。如果该类有父类,则分两种情况来考虑,如果该父类已经实现了可串行化接口。则其父类的相应字段及属性的处理和该类相同;如果该类的父类没有实现可串行化接口,则该类的父类所有的字段属性将不会串行化。

  2)声明为statictransient类型的成员数据不能被串行化。因为static代表类的状态, transient代表对象的临时数据;

  3)相关的类和接口:在java.io包中提供的涉及对象的串行化的类与接口有ObjectOutput接口、ObjectOutputStream类、ObjectInput接口、ObjectInputStream类。

    1ObjectOutput接口:它继承DataOutput接口并且支持对象的串行化,其内的writeObject()方法实现存储一个对象。ObjectInput接口:它继承DataInput接口并且支持对象的串行化,其内的readObject()方法实现读取一个对象。

    2ObjectOutputStream类:它继承OutputStream并且实现ObjectOutput接口。利用该类来实现将对象存储(调用ObjectOutput接口中的writeObject()方法)。ObjectInputStream类:它继承InputStream类并且实现ObjectInput接口。利用该类来实现读取一个对象(调用ObjectInput接口中的readObject()方法)。

  对于父类的处理,如果父类没有实现串行化接口,则其必须有默认的构造函数(即没有参数的构造函数)。否则编译的时候就会报错。在反串行化的时候,默认构造函数被调用。但是若把父类标记为可以串行化,则在反串行化的时候,其默认构造函数不会被调用。这是为什么呢?这是因为Java 对串行化的对象进行反串行化的时候,直接从流里获取其对象数据来生成一个对象实例,而不是通过其构造函数来完成。

import java.io.*;

public class Cat implements Serializable {

        private String name;

        public Cat () {

                this.name = "new cat";

        }

        public String getName() {

                return this.name;

        }

        public void setName(String name) {

                this.name = name;

        }

        public static void main(String[] args) {         

                Cat cat = new Cat();

                try {

                        FileOutputStream fos = new FileOutputStream("catDemo.out");

                        ObjectOutputStream oos = new ObjectOutputStream(fos);

                        System.out.println(" 1> " + cat.getName());

                        cat.setName("My Cat");                       

                        oos.writeObject(cat);

                        oos.close();                       

                } catch (Exception ex) {  ex.printStackTrace();   }

                try {

                        FileInputStream fis = new FileInputStream("catDemo.out");

                        ObjectInputStream ois = new ObjectInputStream(fis);

                        cat = (Cat) ois.readObject();

                        System.out.println(" 2> " + cat.getName());

                        ois.close();

                } catch (Exception ex) {

                        ex.printStackTrace();

                }

        }

}//writeObjectreadObject本身就是线程安全的,传输过程中是不允许被并发访问的。所以对象能一个一个接连不断的传过来

转载自:http://blog.youkuaiyun.com/yakihappy/article/details/3979373

<think>好的,我现在需要回答用户关于Java序列化和反序列化的定义及实现机制的问题。首先,我需要回顾一下已有的引用资料,确保信息的准确性。 根据引用[1],序列化是将Java对象转换为字节序列的过程,反序列化则是相反。引用[2]补充说,这主要用于网络传输和持久化存储。用户想知道实现机制,所以需要提到Serializable接口,如引用[3]所述,这是一个标记接口,没有方法。此外,可能还需要提到其他方法,比如Protocol Buffers,引用[4]提到了这一点。 接下来,我需要组织答案的结构。首先定义序列化和反序列化,然后分点说明实现机制。需要包括基本实现(Serializable接口)、transient关键字、自定义序列化方法、Externalizable接口以及第三方库。同时,要确保使用正确的中文术语,并且行内公式如$...$格式正确,但这里可能不涉及数学公式。不过用户的问题中没有数学内容,所以可能不需要使用公式,但需要检查是否有变量或代码需要处理。例如,代码块需要用三个反引号包裹,并标明语言。 然后,生成相关问题时要基于已有的内容,比如原理、异常处理、不同方法的优缺点、应用场景和第三方库比较。需要确保问题有针对性,并且用户可能感兴趣。 最后,检查引用标注是否正确,每个引用末尾加上[^n],并且引用标识与来源对应。例如,引用[1]、[2]、[3]、[4]分别对应不同的内容,需要正确对应到回答中的相关部分。 现在,整理思路,确保每个部分清晰,并且符合用户的要求。比如,用户可能希望了解如何具体实现序列化,所以需要给出示例代码,如实现Serializable接口的类,以及writeObject和readObject方法的使用。同时,提到transient关键字的作用,避免敏感数据被序列化。 在提到Externalizable接口时,需要指出它与Serializable的不同,需要重写方法。而第三方库如Protocol Buffers,则强调其高效和跨语言特性。 最后,生成的相关问题需要涵盖定义、实现细节、异常处理、优缺点比较和应用场景,这样用户可以有进一步学习的路径。</think>### Java 序列化与反序列化的定义及实现机制 #### 1. 定义 - **序列化**:将Java对象的状态转换为字节序列的过程,以便存储到文件、数据库或通过网络传输[^1][^2]。 - **反序列化**:将字节序列恢复为原始Java对象的过程[^2]。 #### 2. Java序列化实现机制 **(1)基本实现:`Serializable`接口** Java通过`java.io.Serializable`接口实现序列化。该接口是一个标记接口(无方法定义),只需在类中声明即可: ```java public class User implements Serializable { private String name; private transient int password; // transient修饰的字段不会被序列化 } ``` - **`transient`关键字**:标记敏感字段(如密码),阻止其被序列化[^2][^3]。 **(2)自定义序列化** 通过重写`writeObject()`和`readObject()`方法控制序列化逻辑: ```java private void writeObject(ObjectOutputStream oos) throws IOException { oos.defaultWriteObject(); // 默认序列化 oos.writeObject("加密后的密码"); } private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException { ois.defaultReadObject(); // 默认反序列化 String pwd = (String) ois.readObject(); } ``` **(3)`Externalizable`接口** 需强制实现`writeExternal()`和`readExternal()`方法,提供更细粒度的控制: ```java public class User implements Externalizable { @Override public void writeExternal(ObjectOutput out) { // 自定义序列化逻辑 } @Override public void readExternal(ObjectInput in) { // 自定义反序列化逻辑 } } ``` **(4)第三方库支持** 如Protocol Buffers、JSON或XML序列化工具,适用于跨语言或高性能场景[^4]。例如: ```java // Protocol Buffers示例 UserProto.User user = UserProto.User.newBuilder().setName("Alice").build(); byte[] bytes = user.toByteArray(); // 序列化 UserProto.User parsedUser = UserProto.User.parseFrom(bytes); // 反序列化 ``` #### 3. 核心原理 序列化通过`ObjectOutputStream`将对象转为字节流,反序列化通过`ObjectInputStream`恢复对象。序列化ID(`serialVersionUID`)用于验证版本一致性,若未显式定义,JVM会自动生成,但可能导致兼容性问题。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值