总结Java对象被序列化的两种方法

Java对象为什么需要被序列化

  • 序列化能够将对象转为二进制流,对象就可以方便的在网络中被传输和保存。

实现序列化的方式

  • 实现Serializable接口
  • 实现Externalizable接口

**这两个接口的区别是:**Serializable接口会自动给对象的所有属性标记为可被序列化。而Externalizable接口默认不给任何属性标记可被序列化,如果需要序列化,需要重写两个方法,分别是writeExternal()和readExternal(),然后在这两个方法中标记需要被序列化的对象属性。

实现这两个接口,只是表示该对象可以被序列化,真正的做序列化操作,需要ObjectOutputStream对象操作。接下来就用编码的方式体现序列化。

先写个序列化操作的工具类,用于实现序列化和反序列化。

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

/**
 * 序列化操作工具类
 * @author 杨33
 * @date 2020/6/21 15:22
 */
public class SerializeUtil {
    /**
     * 将对象转成字节数组
     * @param object 需要序列化的对象
     * @return
     * @throws IOException
     */
    public static byte[] serialize(Object object) throws IOException{
        if(object == null){
            return null;
        }
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
        objectOutputStream.writeObject(object);
        return byteArrayOutputStream.toByteArray();
    }

    /**
     * 反序列化
     * @param bytes 对象字节数组
     * @throws IOException
     * @throws ClassNotFoundException
     */
    public static Object unserialize(byte[] bytes) throws IOException, ClassNotFoundException{
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
        ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
        return objectInputStream.readObject();
    }
}

先来实现一个Serializable接口

/**
 * @author 杨33
 * @date 2020/6/21 14:20
 */
public class Owner implements Serializable {
    private String name;

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

测试下:

import java.io.IOException;
/**
 * @author 杨33
 * @date 2020/6/21 14:54
 */
public class Demo {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        Owner owner = new Owner();
        owner.setName("李四");
        //序列化
        byte[] serialize = SerializeUtil.serialize(owner);
        System.out.println("序列化的效果:" + serialize);
        //反序列化
        owner = (Owner)SerializeUtil.unserialize(serialize);
        System.out.println("反序列化的效果:" + owner.getName());
    }
}

控制台打印结果:

序列化的效果:[B@58ca40be
反序列化的效果:李四

如果这个name字段不需要被序列化,可以使用关键字transient修饰,比如:

private transient String name;

此时测试一下,name字段就不会被序列化,反序列化后拿到的值就为null。

序列化的效果:[B@4ca49360
反序列化的效果:null

再实现一个Externalizable接口

/**
 * @author 杨33
 * @date 2020/6/21 14:20
 */
public class Medium implements Externalizable {
    private String name;
    private String sex;

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }

    public void writeExternal(ObjectOutput out) throws IOException {
        out.writeObject(name);
        out.writeObject(sex);
    }

    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        name = (String) in.readObject();
        sex = (String) in.readObject();
    }
}

测试下:

import java.io.IOException;
/**
 * @author 杨33
 * @date 2020/6/21 14:54
 */
public class Demo {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        Medium medium = new Medium();
        medium.setName("李四");
        medium.setSex("女");
        //序列化
        byte[] serialize = SerializeUtil.serialize(medium);
        System.out.println("序列化的效果:" + serialize);
        //反序列化
        medium = (Medium)SerializeUtil.unserialize(serialize);
        System.out.println("反序列化的效果:" + medium.getName());
        System.out.println("反序列化的效果:" + medium.getSex());
    }
}

控制台打印结果:

序列化的效果:[B@71d9a2ab
反序列化的效果:李四
反序列化的效果:女

如果字段sex不需要被序列化,那么可以在方法writeExternal()和readExternal()中去掉设置sex字段的代码。最后测试,sex字段不会被序列化,反序列化后拿到的值就为null。

序列化的效果:[B@746c2f2
反序列化的效果:李四
反序列化的效果:null

到此这篇关于总结Java对象被序列化的两种方法的文章就介绍到这了,更多相关Java对象被序列化内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Java IO流对象的序列化和反序列化实例详解

    Java-IO流 对象的序列化和反序列化 序列化的基本操作 1.对象序列化,就是将Object转换成byte序列,反之叫对象的反序列化. 2.序列化流(ObjectOutputStream),writeObject 方法用于将对象写入输出流中: 反序列化流(ObjectInputStream),readObject 方法用于从输入流中读取对象. 3.序列化接口(Serializeable) 对象必须实现序列化接口,才能进行序列化,否则会出现异常.这个接口没有任何方法,只是一个标准. packag

  • 实例分析java对象的序列化和反序列化

    引言: 序列化是将对象的状态信息转换为可以存储或传输的形式的过程,在序列化期间,对象将其带你过去的状态写入到临时或持储存区,反序列化就是重新创建对象的过程,此对象来自于临时或持久储存区. 序列化的作用: 就好比如存储数据到数据库,将一些数据持久化到数据库中,而有时候需要将对象持久化,虽然说将对象状态持久化的方式有很多,但是java给我们提供了一种很便捷的方式,那就是序列化,序列化可以实现对象到文件之间的直接转换,实现细节对我们隐藏. 具体的三种用途: •将对象的状态信息持久化保存到硬盘上 •将对

  • java对象的序列化和反序列化

    本文实例为大家分享了java对象的序列化和反序列化,供大家参考,具体内容如下 1. 什么是序列化        将对象转换为字节流保存起来,比如保存到文件里,并在以后还原这个对象,这种机制叫做对象序列化.(补充一句:把对象保存到永久存储设备上称为持久化) 2. 怎么实现序列化        需要实现Serializable接口,java对象实现了这个接口就表明这个这个类的对象是可序列化的. 3. 序列化的注意事项 (1) 当一个对象序列化时,只能保存对象的非静态成员变量,不能保存方法和静态成员变

  • 详解Java 对象序列化和反序列化

    之前的文章中我们介绍过有关字节流字符流的使用,当时我们对于将一个对象输出到流中的操作,使用DataOutputStream流将该对象中的每个属性值逐个输出到流中,读出时相反.在我们看来这种行为实在是繁琐,尤其是在这个对象中属性值很多的时候.基于此,Java中对象的序列化机制就可以很好的解决这种操作.本篇就简单的介绍Java对象序列化,主要内容如下: 简洁的代码实现 序列化实现的基本算法 两种特殊的情况 自定义序列化机制 序列化的版本控制 一.简洁的代码实现 在介绍对象序列化的使用方法之前,先看看

  • java对象序列化与反序列化原理解析

    这篇文章主要介绍了java对象序列化与反序列化原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 一.序列化和反序列化的概念 对象转换为字节序列的过程称为对象的序列化.把字节序列恢复为对象的过程称为对象的反序列化. 二.序列化和反序列化的作用 对象的序列化主要有两种用途: 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中. 在网络上传送对象的字节序列.网络上传输的都是二进制序列. 在很多应用中,需要对某些对象进行序列化,让它们离开内

  • Java对象的序列化与反序列化详解

    一.序列化和反序列化的概念 把对象转换为字节序列的过程称为对象的序列化,把字节序列恢复为对象的过程称为对象的反序列化. 对象的序列化主要有两种途径: Ⅰ . 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中 Ⅱ.  在网络上传送对象的字节序列. 当两个进程在进行远程通信时,彼此可以发送各种类型的数据.无论是何种类型的数据,都会以二进制序列的形式在网络上传送.发送方需要把这个Java对象转换为字节序列,才能在网络上传送:接收方则需要把字节序列再恢复为Java对象. 二.序列化API 1.

  • 总结Java对象被序列化的两种方法

    Java对象为什么需要被序列化 序列化能够将对象转为二进制流,对象就可以方便的在网络中被传输和保存. 实现序列化的方式 实现Serializable接口 实现Externalizable接口 **这两个接口的区别是:**Serializable接口会自动给对象的所有属性标记为可被序列化.而Externalizable接口默认不给任何属性标记可被序列化,如果需要序列化,需要重写两个方法,分别是writeExternal()和readExternal(),然后在这两个方法中标记需要被序列化的对象属性

  • java 获取mac地址的两种方法(推荐)

    我在网上找了一下获取mac地址的方法,找了两种比较不太一样的方法. 第一种 public static void main(String[] args) throws Exception { InetAddress ia = InetAddress.getLocalHost(); System.out.println(getMACAddress(ia)); } private static String getMACAddress(InetAddress ia) throws Exception

  • Java创建子线程的两种方法

    摘要: 其实两种方法归结起来看还是一种,都是利用Thread的构造器进行创建,区别就是一种是无参的,一种是有参的. 一.继承Thread线程类: 通过继承Thread类,重写run方法,子类对象就可以调用start方法启动线程,JVM就会调用此线程的run方法. 代码如下: public class MyThread extends Thread { public MyThread() { super(); } @Override public void run() { } // 线程执行结束

  • java检查服务器的连通两种方法代码分享

    首先要了解一下ping的内容. 概述 PING (Packet Internet Groper),因特网包探索器,用于测试网络连接量的程序.Ping发送一个ICMP(Internet Control Messages Protocol)即因特网信报控制协议:回声请求消息给目的地并报告是否收到所希望的ICMPecho (ICMP回声应答).它是用来检查网络是否通畅或者网络连接速度的命令.作为一个生活在网络上的管理员或者黑客来说,ping命令是第一个必须掌握的DOS命令,它所利用的原理是这样的:利用

  • JavaScript判断对象和数组的两种方法

    在调用后端接口时,由于后端接口的不规范统一,接口最外层在没有数据时返回的是空数组(其实更想要的是空json对象),而在有数据时返回的是json对象,所以在接收到后端返回的接口时就需要首先判断返回的数据是对象还是数组,这里提供一些方法  方法一: //判断是否为数组 function isArray(obj) { return obj instanceof Array; } //判断是否为对象 function isObject(obj) { return obj instanceof Objec

  • Java 实现图片压缩的两种方法

    问题背景. 典型的情景:Nemo社区中,用户上传的图片免不了要在某处给用户做展示. 如用户上传的头像,那么其他用户在浏览该用户信息的时候,就会需要回显头像信息了. 用户上传的原图可能由于清晰度较高而体积也相对较大,考虑用户流量带宽,一般而言我们都不会直接体积巨大的原图直接丢给用户让用户慢慢下载. 这时候通常我们会在服务器对图片进行压缩,然后把压缩后的图片内容回显给用户. 压缩方案: 这里主要找了两个java中常用的图片压缩工具库:Graphics和Thumbnailator. 1.Graphic

  • Java唤醒本地应用的两种方法详解

    目录 引言 1. Runtime使用方式 2. ProcessBuilder使用方式 3. 小结 引言 作为一个后端同学,经常被安全的小伙伴盯上,找一找安全漏洞:除了常说的注入之外,还有比较吓人的执行远程命令,唤醒本地应用程序等:然后有意思的问题就来了,写了这么多年的代码,好像还真没有尝试过用java来唤醒本地应用程序的 比如说一个最简单的,打开本地的计算器,应该怎么搞? 接下来本文将介绍一下如何使用java打开本地应用,以及打开mac系统中特殊一点的处理方式(直白来说就是不同操作系统,使用姿势

  • 使用java获取md5值的两种方法

    Message Digest Algorithm MD5(中文名为消息摘要算法第五版)为计算机安全领域广泛使用的一种散列函数,是一种比较常用的哈希算法. java中可以用两种方法实现,我们先说麻烦一点的,代码: 复制代码 代码如下: public class md5_test { //MD5的字符串常量 private final static String[] hexDigits = { "0", "1", "2", "3"

  • Java中分割字符串的两种方法实例详解

    前言 相信大家应该都知道在java编程中,有时候我们需要把一个字符串按照某个特定字符.字母等作为截点分割这个字符串,这样我们就可以使用这个字符串的一部分或者把所有截取的内容保存到数组里等操作.下面这篇文章就给大家分享了两种分割的方法,下面来一起看看吧. 一.java.lang.String 的 split() 方法, JDK 1.4 or later public String[] split(String regex,int limit) 示例代码 public class StringSpl

  • java生成随机字符串的两种方法

    本文实例为大家分享了java生成随机字符串的具体代码,供大家参考,具体内容如下 import java.util.Random; public class CharacterUtils { //方法1:length为产生的位数 public static String getRandomString(int length){ //定义一个字符串(A-Z,a-z,0-9)即62位: String str="zxcvbnmlkjhgfdsaqwertyuiopQWERTYUIOPASDFGHJKLZ

随机推荐