目次
1. 質問:
2. シリアル化と逆シリアル化
3. シリアル化と逆シリアル化の使用シナリオ
Serializable インターフェイスを実装する
transient private String sex;
ログイン後にコピー
ログイン後にコピー
" >
transient private String sex;
ログイン後にコピー
ログイン後にコピー
1.一時的な変更を削除します

2、序列化与反序列化

3、序列化和反序列化的使用场景
5、如何实现序列化和反序列化
Serializable接口" >5.1 、实现Serializable接口
5.2、ObjectOutputStream与ObjectInputStream
6、transient
6.1 defaultWriteObject和defaultReadObject()

JAVAシリアル化

Feb 24, 2017 am 09:44 AM

1. 質問:

オブジェクトをファイルに書き込みたいが、バイト ストリームでも文字ストリームでも要件を満たせない場合、オブジェクトをファイルに書き込むにはどうすればよいですか?
バイト文字ストリームを使用する場合、オブジェクトをバイト/文字に変換してからファイルに書き込む必要があります。ただし、バイト文字ストリームにはオブジェクトをバイトに変換する方法がありません。

2. シリアル化と逆シリアル化

Java シリアル化: オブジェクトをバイトに変換するプロセス。これはまさに私のニーズを満たします。
Java 逆シリアル化: バイトをオブジェクトに復元するプロセス
これは、オブジェクトをファイルに書き込み、オブジェクトを読み取るという要求を満たします

3. シリアル化と逆シリアル化の使用シナリオ

  • a. オブジェクトをハードディスクに書き込みます。

    b、ネットワーク間の送信

  • テキスト、オーディオ、ビデオなどがネットワーク上で送信される場合、ネットワーク上でオブジェクトを送信したい場合は、シリアル化とを使用する必要があります。逆シリアル化はデータの送受信を満たします。
      ###4. シリアル化と逆シリアル化の利点
    • まず、シリアル化を通じてデータの永続性を実現し、データをローカル ハードディスクに永続的に保存します。

      次に、リモート ネットワーク通信を実現し、シリアル化を使用して一連のバイトを作成します。オブジェクトはネットワーク経由で送信できます。


    • 5. シリアル化と逆シリアル化の実装方法
5.1.

Serializable インターフェイスを実装する

Serializable インターフェイスにはメソッドがありませんが、このクラスがシリアル化できることを Java メカニズムに伝えるための識別子のみを提供します。 ; この識別子が作成されていない場合、SerialVersionUID は

クラス名、インターフェース名、メンバーのメソッドと属性

などに基づいて
64ビットのハッシュフィールドを生成します。

SerialVersionUID がない場合、通常、シリアル化後にクラスの属性が変更されると、逆シリアル化中にエラーが報告されます。疲れた属性が変更されているため、Java メカニズムは、 SerialVersionUID が元の ID と一致しないため、逆シリアル化が失敗しました。

  • SerialVersionUID の実装が設定されている場合、属性またはメソッドが追加された場合でも、シリアル化と逆シリアル化を実行できます。
  • 新しく追加された属性値のみが null であるか、そうでないように見えます。属性の値が削除されます。
    • package com.chb.test;import java.io.Serializable;public class Student implements Serializable{
          //序列化标识
          private static final long serialVersionUID = 1L;    
          private String name;    
          private int age;    
          private String sex;    
          public Student() {
          }    
          public Student(String name, int age, String sex) {        
          super();        
          this.name = name;        
          this.age = age;        
          this.sex = sex;
          }    
          @Override
          public String toString() {        
          return "Student{"
                      +"姓名:"+this.name
                      +"性别:"+this.sex
                      +"年龄"+this.age
                      + "}";
          }    
          /**setter getter 省略。。。*/    
          }
      ログイン後にコピー

      5.2、ObjectOutputStream と ObjectInputStream
    Serializalable インターフェイスは表現のみを提供し、オブジェクトをバイナリ シーケンスに変換し、バイナリ シーケンスをオブジェクトに復元するのは、ObjectOutputStream と OjbectInputStream によって提供される 2 つのメソッド、writeObject() と readObject() です。

writeObject()

  • public static void write(Student s1) throws Exception {
            FileOutputStream fos = new FileOutputStream(filename);
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(s1);
            oos.close();
    }
    ログイン後にコピー
    ログイン後にコピー

  • readObject()
  • public static Student read() throws Exception {
            FileInputStream fis = new FileInputStream(filename);
            ObjectInputStream ois = new ObjectInputStream(fis);
            Student stu = new Student();        //使用readeObject()进行反序列化
            stu= (Student) ois.readObject();
            ois.close();        return stu;
    }
    ログイン後にコピー
    ログイン後にコピー

    6. 場合によっては、一部の機密フィールドやクラスの参照型をシリアル化すべきではありません。メンバーはシリアル化できません。このため、

    transient
  • を使用してこれらのメンバーを変更し、シリアル化されないようにする必要があります。例: 銀行口座オブジェクト、口座金額をシリアル化したくない場合。
上記の Student クラスを変更し、transient

transient private String sex;
ログイン後にコピー
ログイン後にコピー

を使用して sex 属性を変更し、それをシリアル化

Student s1 = new Student("roase",19, "女");
write(s1);
ログイン後にコピー
ログイン後にコピー
deserialize して、読み取りオブジェクトが見つかりました: sex が null であり、transient によって変更された属性がシリアル化されないことを示します。

6.1defaultWriteObjectとdefaultReadObject()

上記の一時的なメンバーの年齢について、ここでシリアル化可能および逆シリアル化したい場合、何をすべきか:
JAVAシリアル化

1.一時的な変更を削除します

    2. 2 つのメソッドを提供します
  •     private void writeObject(ObjectOutputStream out) throws Exception{        
        out.defaultWriteObject();        
        out.writeInt(age);
        }    
        private void  readObject(ObjectInputStream in) throws Exception {        
        in.defaultReadObject();
            age=in.readInt();
        }
    ログイン後にコピー
    ログイン後にコピー
  • writeObject() メソッドでは、ObjectOutputStream のdefaultWriteObject() メソッドが最初に呼び出され、このメソッドは
  • デフォルトのシリアル化メカニズム

    を実行し、この時点では age は無視されます。次に、writeInt() メソッドを呼び出して、age フィールドを ObjectOutputStream に明示的に書き込みます。 readObject() の機能はオブジェクトを読み取ることであり、その原理は writeObject() メソッドと同じです。 read() アプリケーションを再度実行すると、次の出力が得られます:

1. 問題:

オブジェクトをファイルに書き込みたい場合、バイト ストリームでも文字ストリームでも書き込みできないことがわかります。要件を満たします。

オブジェクトをファイルに書き込むには? JAVAシリアル化

バイト文字ストリームを使用する場合、オブジェクトをバイト/文字に変換してからファイルに書き込む必要があります。ただし、バイト文字ストリームにはオブジェクトをバイトに変換する方法がありません。

2、序列化与反序列化

Java序列化:将对象转为字节的过程,这正好符合我的需求。
Java反序列化:将字节恢复为对象的过程
这满足我们想文件中写对象,和读取对象

3、序列化和反序列化的使用场景

  • a、将对象写道硬盘中;

  • b、网络间传输

    • 当在网络上传送文本,音频,视频等,都是转化为二进制序列传送,我们要在网络上传送对象,就必须使用序列化和反序列化,满足数据的发送和接收。
      ###4、序列化和反序列化的好处
      一、实现数据的持久化,通过序列化将数据永久的保存在本地的硬盘上;
      二、实现远程网络通信,利用序列化,使得在网络上可以传输对象的字节序列。

5、如何实现序列化和反序列化

5.1 、实现Serializable接口

  Serializable接口没有任何方法,只是提供一个标识 , 用来告诉java机制该类可以被序列化;
   如果没有创建这个标识,java机制将会自动的创建一个,SerialVersionUID是根据类名, 接口名,成员方法及属性等来生成一个64位哈希字段

  • 如果没有SerialVersionUID, 通常我们会发现,如果在序列化后,修改了类的属性, 在进行反序化,会报错,因为累的属性修改了,java机制会重新创建一个SerialVersionUID, 导致与原来的ID不一致, 反序列化失败。

    • 如果设置了实现SerialVersionUID, 保证版本的兼容性, 即使添加了属性或方法, 仍然能进行序列化和反序列化, 只是新添加的属性值为null,或不显示被删除属性的值。

package com.chb.test;import java.io.Serializable;public class Student implements Serializable{
    //序列化标识
    private static final long serialVersionUID = 1L;    
    private String name;    
    private int age;    
    private String sex;    
    public Student() {
    }    
    public Student(String name, int age, String sex) {        
    super();        
    this.name = name;        
    this.age = age;        
    this.sex = sex;
    }    
    @Override
    public String toString() {        
    return "Student{"
                +"姓名:"+this.name
                +"性别:"+this.sex
                +"年龄"+this.age
                + "}";
    }    
    /**setter getter 省略。。。*/    }
ログイン後にコピー

5.2、ObjectOutputStream与ObjectInputStream

  Serializalable接口只是提供一个表示,将对象转为二进制序列,和二进制序列恢复成对象是由ObjectOutputStream和OjbectInputStream提供的两个方法:writeObject()和readObject()

  • writeObject()

public static void write(Student s1) throws Exception {
        FileOutputStream fos = new FileOutputStream(filename);
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        oos.writeObject(s1);
        oos.close();
}
ログイン後にコピー
ログイン後にコピー
  • readObject()

public static Student read() throws Exception {
        FileInputStream fis = new FileInputStream(filename);
        ObjectInputStream ois = new ObjectInputStream(fis);
        Student stu = new Student();        //使用readeObject()进行反序列化
        stu= (Student) ois.readObject();
        ois.close();        return stu;
}
ログイン後にコピー
ログイン後にコピー

6、transient

在某种场合,我们对某些敏感字段不要进行序列化,或者类的引用类型的成员不能够进行序列化, 这是我们需要使用transient来修饰这些成员, 以避免它们被序列化。如:银行账户对象,不希望对账户金额进行序列化。
修改上面的Student类,将sex属性使用transient修饰

transient private String sex;
ログイン後にコピー
ログイン後にコピー

再进行序列化

Student s1 = new Student("roase",19, "女");
write(s1);
ログイン後にコピー
ログイン後にコピー

反序列化, 读取的对象发现:sex为null,说明被transient修饰的属性不会被序列化。
JAVAシリアル化

6.1 defaultWriteObject和defaultReadObject()

对于上面的被transient的成员age, 如果我们想让它能够在此序列化和反序列化,要如何做:

  • 1、去掉transient的修饰

  • 2、提供两个方法

    private void writeObject(ObjectOutputStream out) throws Exception{        
    out.defaultWriteObject();        
    out.writeInt(age);
    }    
    private void  readObject(ObjectInputStream in) throws Exception {        
    in.defaultReadObject();
        age=in.readInt();
    }
ログイン後にコピー
ログイン後にコピー

在writeObject()方法中会先调用ObjectOutputStream中的defaultWriteObject()方法,该方法会执行默认的序列化机制,此时会忽略掉age字段。然后再调用writeInt()方法显示地将age字段写入到ObjectOutputStream中。readObject()的作用则是针对对象的读取,其原理与writeObject()方法相同。再次执行read()应用程序,则又会有如下输出:

JAVAシリアル化

 以上就是JAVA之序列化的内容,更多相关内容请关注PHP中文网(www.php.cn)!


このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Javaの平方根 Javaの平方根 Aug 30, 2024 pm 04:26 PM

Java の平方根のガイド。ここでは、Java で平方根がどのように機能するかを、例とそのコード実装をそれぞれ示して説明します。

Javaの完全数 Javaの完全数 Aug 30, 2024 pm 04:28 PM

Java における完全数のガイド。ここでは、定義、Java で完全数を確認する方法、コード実装の例について説明します。

Java の乱数ジェネレーター Java の乱数ジェネレーター Aug 30, 2024 pm 04:27 PM

Java の乱数ジェネレーターのガイド。ここでは、Java の関数について例を挙げて説明し、2 つの異なるジェネレーターについて例を挙げて説明します。

ジャワのウェカ ジャワのウェカ Aug 30, 2024 pm 04:28 PM

Java の Weka へのガイド。ここでは、weka java の概要、使い方、プラットフォームの種類、利点について例を交えて説明します。

Javaのスミス番号 Javaのスミス番号 Aug 30, 2024 pm 04:28 PM

Java のスミス番号のガイド。ここでは定義、Java でスミス番号を確認する方法について説明します。コード実装の例。

Java Springのインタビューの質問 Java Springのインタビューの質問 Aug 30, 2024 pm 04:29 PM

この記事では、Java Spring の面接で最もよく聞かれる質問とその詳細な回答をまとめました。面接を突破できるように。

Java 8 Stream Foreachから休憩または戻ってきますか? Java 8 Stream Foreachから休憩または戻ってきますか? Feb 07, 2025 pm 12:09 PM

Java 8は、Stream APIを導入し、データ収集を処理する強力で表現力のある方法を提供します。ただし、ストリームを使用する際の一般的な質問は次のとおりです。 従来のループにより、早期の中断やリターンが可能になりますが、StreamのForeachメソッドはこの方法を直接サポートしていません。この記事では、理由を説明し、ストリーム処理システムに早期終了を実装するための代替方法を調査します。 さらに読み取り:JavaストリームAPIの改善 ストリームを理解してください Foreachメソッドは、ストリーム内の各要素で1つの操作を実行する端末操作です。その設計意図はです

Java での日付までのタイムスタンプ Java での日付までのタイムスタンプ Aug 30, 2024 pm 04:28 PM

Java での日付までのタイムスタンプに関するガイド。ここでは、Java でタイムスタンプを日付に変換する方法とその概要について、例とともに説明します。

See all articles