Apa itu serialisasi objek?

Jawaban:

400

Serialisasi adalah konversi suatu objek ke serangkaian byte, sehingga objek tersebut dapat dengan mudah disimpan ke penyimpanan persisten atau dialirkan melalui tautan komunikasi. Aliran byte kemudian dapat deserialized - dikonversi menjadi replika objek asli.

TarkaDaal
sumber
16
apakah ini wajib? saya harus membuat cerita bersambung data sebelum mengirimnya? format apa itu dikonversi?
Francisco Corrales Morales
15
@FranciscoCorralesMorales - Di belakang layar, semua data akan diserialisasi sebelum dikirim melalui aliran. Seberapa banyak yang perlu Anda lakukan, dan format apa yang akan digunakan, keduanya tergantung pada platform dan perpustakaan yang Anda gunakan.
TarkaDaal
3
@FranciscoCorralesMorales Bagaimana Anda mengatakannya? Maksud saya, formatnya tergantung pada platform dan libraries. Saya benar-benar ingin tahu formatnya.
JAVA
1
Apakah hanya berlaku untuk objek? Bisakah kita membuat serialisasi variabel (dideklarasikan tanpa menggunakan objek)?
Rumado
@Rumado Objects only
anKotliner
395

Anda dapat menganggap serialisasi sebagai proses mengubah instance objek menjadi urutan byte (yang mungkin biner atau tidak tergantung pada implementasinya).

Ini sangat berguna ketika Anda ingin mengirimkan satu objek data di jaringan, misalnya dari satu JVM ke yang lain.

Di Jawa, mekanisme serialisasi dibangun ke platform, tetapi Anda perlu mengimplementasikan antarmuka Serializable untuk membuat objek serializable.

Anda juga dapat mencegah beberapa data di objek Anda menjadi serial dengan menandai atributnya sebagai sementara .

Akhirnya Anda dapat mengganti mekanisme default, dan menyediakan mekanisme Anda sendiri; ini mungkin cocok dalam beberapa kasus khusus. Untuk melakukan ini, Anda menggunakan salah satu fitur tersembunyi di java .

Penting untuk diperhatikan bahwa yang diserialkan adalah "nilai" dari objek, atau konten, dan bukan definisi kelas. Dengan demikian metode tidak serial.

Berikut ini adalah contoh yang sangat mendasar dengan komentar untuk memudahkan pembacaannya:

import java.io.*;
import java.util.*;

// This class implements "Serializable" to let the system know
// it's ok to do it. You as programmer are aware of that.
public class SerializationSample implements Serializable {

    // These attributes conform the "value" of the object.

    // These two will be serialized;
    private String aString = "The value of that string";
    private int    someInteger = 0;

    // But this won't since it is marked as transient.
    private transient List<File> unInterestingLongLongList;

    // Main method to test.
    public static void main( String [] args ) throws IOException  { 

        // Create a sample object, that contains the default values.
        SerializationSample instance = new SerializationSample();

        // The "ObjectOutputStream" class has the default 
        // definition to serialize an object.
        ObjectOutputStream oos = new ObjectOutputStream( 
                               // By using "FileOutputStream" we will 
                               // Write it to a File in the file system
                               // It could have been a Socket to another 
                               // machine, a database, an in memory array, etc.
                               new FileOutputStream(new File("o.ser")));

        // do the magic  
        oos.writeObject( instance );
        // close the writing.
        oos.close();
    }
}

Ketika kita menjalankan program ini, file "o.ser" dibuat dan kita dapat melihat apa yang terjadi di belakang.

Jika kita mengubah nilai: someInteger ke, misalnya Integer.MAX_VALUE , kita dapat membandingkan output untuk melihat apa perbedaannya.

Berikut screenshot yang menunjukkan perbedaan itu:

teks alternatif

Bisakah Anda melihat perbedaannya? ;)

Ada bidang tambahan yang relevan dalam serialisasi Java: The serialversionUID tapi saya kira ini sudah terlalu lama untuk membahasnya.

OscarRyz
sumber
1
@ raam86 contoh adalah objek sedang serial. Anda mungkin berpikir dalam metode utama sebagai program terpisah yang menciptakan objek bertipeSerializationSample
OscarRyz
2
@ raam86 adalah pernyataan pertama dalam metode utama: SerializationSample instance = new SerializationSample();kemudian output dibuat dan objek ditulis ke output itu.
OscarRyz
1
Oh Tidak mengikuti cukup dekat. Bagus!!
raam86
1
@jacktrades Mengapa Anda tidak mencobanya. Cukup salin / tempel contoh dan lihat "NotSerializableException" dilemparkan :)
OscarRyz
1
@jacktrades karena komputer belum diberi tahu bahwa objek tersebut diizinkan bersambung :) apa yang dimaksud dengan oos?
Chris Bennett
101

Berani menjawab pertanyaan 6 tahun, hanya menambah pemahaman tingkat tinggi bagi orang-orang baru di Jawa

Apa itu Serialisasi?

Mengubah objek menjadi byte

Apa itu Deserialisasi?

Mengkonversi byte kembali ke objek (Deserialization).

Kapan serialisasi digunakan?

Ketika kita ingin Bertahan Objek. Ketika kita ingin objek ada di luar masa pakai JVM.

Contoh Dunia Nyata:

ATM: Ketika pemegang akun mencoba untuk menarik uang dari server melalui ATM, informasi pemegang akun seperti detail penarikan akan diserialisasi dan dikirim ke server di mana detailnya di-deserialisasi dan digunakan untuk melakukan operasi.

Bagaimana serialisasi dilakukan di java.

  1. Implement java.io.Serializableantarmuka (penanda antarmuka sehingga tidak ada metode untuk diterapkan).

  2. Tetap objek: Gunakan java.io.ObjectOutputStreamkelas, aliran filter yang merupakan pembungkus di sekitar aliran byte tingkat yang lebih rendah (untuk menulis objek ke sistem file atau mentransfer objek diratakan di kawat jaringan dan dibangun kembali di sisi lain).

    • writeObject(<<instance>>) - untuk menulis objek
    • readObject() - untuk membaca Obyek berseri

Ingat:

Saat Anda membuat serial objek, hanya status objek yang akan disimpan, bukan file atau metode kelas objek.

Ketika Anda membuat serial objek 2-byte, Anda melihat file serial 51 byte.

Langkah-langkah bagaimana objek serial dan de-serial.

Jawaban untuk: Bagaimana cara dikonversi ke file 51 byte?

  • Pertama-tama menulis data sulap aliran serialisasi (STREAM_MAGIC = "AC ED" dan STREAM_VERSION = versi JVM).
  • Kemudian ia menulis metadata dari kelas yang terkait dengan sebuah instance (panjang kelas, nama kelas, serialVersionUID).
  • Kemudian secara rekursif menulis metadata dari superclass sampai ditemukan java.lang.Object.
  • Kemudian dimulai dengan data aktual yang terkait dengan instance.
  • Akhirnya menulis data objek yang terkait dengan instance mulai dari metadata ke konten yang sebenarnya.

Jika Anda tertarik pada informasi lebih mendalam tentang Serialisasi Java, silakan periksa tautan ini .

Sunting : Satu lagi tautan bagus untuk dibaca.

Ini akan menjawab beberapa pertanyaan:

  1. Bagaimana tidak membuat serialisasi bidang apa pun di kelas.
    Jawab: gunakan kata kunci sementara

  2. Ketika kelas anak diserialisasi apakah kelas induk mendapatkan serial?
    Jawab: Tidak, Jika orang tua tidak memperluas bidang orang tua antarmuka Serializable jangan diserialisasi.

  3. Ketika orang tua diserialisasi apakah kelas anak mendapatkan serial?
    Jawab: Ya, secara standar kelas anak juga diserialisasi.

  4. Bagaimana cara menghindari kelas anak dari mendapatkan serial?
    Jawab: a. Mengganti metode writeObject dan readObject dan melempar NotSerializableException.

    b. Anda juga dapat menandai semua bidang sementara di kelas anak.

  5. Beberapa kelas tingkat sistem seperti Thread, OutputStream, dan subkelasnya, dan Socket tidak dapat diserialisasi.
VdeX
sumber
3
terima kasih banyak atas jawaban ringkas ini, itu sangat membantu!
Nobi
21

Serialisasi adalah mengambil objek "langsung" dalam memori dan mengubahnya menjadi format yang dapat disimpan di suatu tempat (mis. Dalam memori, pada disk) dan kemudian "deserialized" kembali menjadi objek langsung.

Kent Boogaart
sumber
14

Saya menyukai cara hadiah @OscarRyz. Meskipun di sini saya melanjutkan kisah serialisasi yang awalnya ditulis oleh @amitgupta.

Meskipun mengetahui tentang struktur kelas robot dan memiliki data bersambung, ilmuwan Bumi tidak dapat melakukan deserialisasi data yang dapat membuat robot berfungsi.

Exception in thread "main" java.io.InvalidClassException:
SerializeMe; local class incompatible: stream classdesc
:

Ilmuwan Mars sedang menunggu pembayaran lengkap. Setelah pembayaran dilakukan, para ilmuwan Mars berbagi versi serialUID dengan para ilmuwan Bumi. Ilmuwan bumi mengaturnya ke kelas robot dan semuanya menjadi baik-baik saja.

noquery
sumber
9

Serialisasi berarti objek yang bertahan di java. Jika Anda ingin menyimpan keadaan objek dan ingin membangun kembali keadaan nanti (mungkin dalam JVM lain) serialisasi dapat digunakan.

Perhatikan bahwa properti suatu objek hanya akan disimpan. Jika Anda ingin menghidupkan kembali objek Anda harus memiliki file kelas, karena variabel anggota hanya akan disimpan dan bukan fungsi anggota.

misalnya:

ObjectInputStream oos = new ObjectInputStream(                                 
                                 new FileInputStream(  new File("o.ser")) ) ;
SerializationSample SS = (SearializationSample) oos.readObject();

The Searializable adalah antarmuka penanda yang menandai bahwa kelas Anda bisa serial. Antarmuka penanda berarti bahwa itu hanya antarmuka kosong dan menggunakan antarmuka itu akan memberi tahu JVM bahwa kelas ini dapat dibuat berseri.

Sathesh
sumber
9

Dua sen saya dari blog saya sendiri:

Berikut adalah penjelasan rinci tentang Serialisasi : (blog saya sendiri)

Serialisasi:

Serialisasi adalah proses mempertahankan keadaan suatu objek. Itu diwakili dan disimpan dalam bentuk urutan byte. Ini dapat disimpan dalam file. Proses untuk membaca keadaan objek dari file dan mengembalikannya disebut deserialization.

Apa perlunya Serialisasi?

Dalam arsitektur modern, selalu ada kebutuhan untuk menyimpan keadaan objek dan kemudian mengambilnya. Sebagai contoh di Hibernate, untuk menyimpan objek kita harus membuat kelas Serializable. Apa yang dilakukannya, adalah bahwa begitu keadaan objek disimpan dalam bentuk byte, ia dapat ditransfer ke sistem lain yang kemudian dapat membaca dari keadaan dan mengambil kelas. Status objek dapat berasal dari database atau jvm yang berbeda atau dari komponen terpisah. Dengan bantuan Serialisasi, kita dapat mengambil status Objek.

Contoh Kode dan penjelasan:

Pertama mari kita lihat di Kelas Item:

public class Item implements Serializable{

    /**
    *  This is the Serializable class
    */
    private static final long serialVersionUID = 475918891428093041L;
    private Long itemId;
    private String itemName;
    private transient Double itemCostPrice;
    public Item(Long itemId, String itemName, Double itemCostPrice) {
        super();
        this.itemId = itemId;
        this.itemName = itemName;
        this.itemCostPrice = itemCostPrice;
      }

      public Long getItemId() {
          return itemId;
      }

     @Override
      public String toString() {
          return "Item [itemId=" + itemId + ", itemName=" + itemName + ", itemCostPrice=" + itemCostPrice + "]";
       }


       public void setItemId(Long itemId) {
           this.itemId = itemId;
       }

       public String getItemName() {
           return itemName;
       }
       public void setItemName(String itemName) {
            this.itemName = itemName;
        }

       public Double getItemCostPrice() {
            return itemCostPrice;
        }

        public void setItemCostPrice(Double itemCostPrice) {
             this.itemCostPrice = itemCostPrice;
        }
}

Dalam kode di atas dapat dilihat bahwa kelas Item mengimplementasikan Serializable .

Ini adalah antarmuka yang memungkinkan kelas menjadi serializable.

Sekarang kita bisa melihat variabel yang disebut serialVersionUID diinisialisasi ke variabel Long. Angka ini dihitung oleh kompiler berdasarkan status kelas dan atribut kelas. Ini adalah angka yang akan membantu jvm mengidentifikasi keadaan suatu objek ketika membaca keadaan objek dari file.

Untuk itu kita bisa melihat di Dokumentasi Oracle resmi:

Runtime serialisasi mengaitkan dengan setiap kelas seri dengan nomor versi, yang disebut serialVersionUID, yang digunakan selama deserialisasi untuk memverifikasi bahwa pengirim dan penerima objek serial telah memuat kelas untuk objek yang kompatibel dengan serialisasi. Jika penerima telah memuat kelas untuk objek yang memiliki serialVersionUID berbeda dari kelas pengirim yang sesuai, maka deserialisasi akan menghasilkan InvalidClassException. Kelas serializable dapat mendeklarasikan serialVersionUID sendiri secara eksplisit dengan mendeklarasikan bidang bernama "serialVersionUID" yang harus statis, final, dan bertipe panjang: ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L; Jika kelas serializable tidak secara eksplisit mendeklarasikan serialVersionUID, maka runtime serialisasi akan menghitung nilai serialVersionUID default untuk kelas tersebut berdasarkan berbagai aspek kelas, seperti yang dijelaskan dalam Spesifikasi Serialisasi Seri Objek Java (TM). Namun, sangat disarankan bahwa semua kelas serializable secara eksplisit mendeklarasikan nilai serialVersionUID, karena perhitungan serialVersionUID default sangat sensitif terhadap detail kelas yang dapat bervariasi tergantung pada implementasi kompiler, dan dengan demikian dapat menghasilkan InvalidClassExceptions yang tidak terduga selama deserialisasi. Oleh karena itu, untuk menjamin nilai serialVersionUID yang konsisten di seluruh implementasi java compiler yang berbeda, kelas serializable harus mendeklarasikan nilai serialVersionUID yang eksplisit. Juga sangat disarankan bahwa deklarasi serialVersionUID eksplisit menggunakan pengubah pribadi jika memungkinkan,

Jika Anda perhatikan ada kata kunci lain yang kami gunakan yang sementara .

Jika suatu bidang tidak serializable, itu harus ditandai sementara. Di sini kami menandai itemCostPrice sebagai sementara dan tidak ingin itu ditulis dalam file

Sekarang mari kita lihat bagaimana cara menulis status suatu objek dalam file dan kemudian membacanya dari sana.

public class SerializationExample {

    public static void main(String[] args){
        serialize();
       deserialize();
    } 

    public static void serialize(){

         Item item = new Item(1L,"Pen", 12.55);
         System.out.println("Before Serialization" + item);

         FileOutputStream fileOut;
         try {
             fileOut = new FileOutputStream("/tmp/item.ser");
             ObjectOutputStream out = new ObjectOutputStream(fileOut);
             out.writeObject(item);
             out.close();
             fileOut.close();
             System.out.println("Serialized data is saved in /tmp/item.ser");
           } catch (FileNotFoundException e) {

                  e.printStackTrace();
           } catch (IOException e) {

                  e.printStackTrace();
           }
      }

    public static void deserialize(){
        Item item;

        try {
                FileInputStream fileIn = new FileInputStream("/tmp/item.ser");
                ObjectInputStream in = new ObjectInputStream(fileIn);
                item = (Item) in.readObject();
                System.out.println("Serialized data is read from /tmp/item.ser");
                System.out.println("After Deserialization" + item);
        } catch (FileNotFoundException e) {
                e.printStackTrace();
        } catch (IOException e) {
               e.printStackTrace();
        } catch (ClassNotFoundException e) {
               e.printStackTrace();
        }
     }
}

Dalam contoh di atas kita dapat melihat contoh serialisasi dan deserialisasi objek.

Untuk itu kami menggunakan dua kelas. Untuk membuat serial objek, kami telah menggunakan ObjectOutputStream. Kami telah menggunakan metode writeObject untuk menulis objek dalam file.

Untuk Deserializing kami telah menggunakan ObjectInputStream yang membaca dari objek dari file. Menggunakan readObject untuk membaca data objek dari file.

Output dari kode di atas akan seperti:

Before SerializationItem [itemId=1, itemName=Pen, itemCostPrice=12.55]
Serialized data is saved in /tmp/item.ser
After DeserializationItem [itemId=1, itemName=Pen, itemCostPrice=null]

Perhatikan bahwa itemCostPrice dari objek deserialized adalah null karena tidak ditulis.

Kami telah membahas dasar-dasar Serialisasi Jawa pada bagian I artikel ini.

Sekarang mari kita bahas secara mendalam dan bagaimana cara kerjanya.

Pertama mari kita mulai dengan cairan serial.

The serialVersionUID digunakan sebagai kontrol versi di kelas Serializable.

Jika Anda tidak secara eksplisit mendeklarasikan serialVersionUID, JVM akan melakukannya untuk Anda secara otomatis, berdasarkan berbagai properti dari kelas Serializable.

Algoritma Java Menghitung serialversionuid (Baca lebih detail di sini)

  1. Nama kelas.
    1. Pengubah kelas ditulis sebagai integer 32-bit.
    2. Nama setiap antarmuka diurutkan berdasarkan nama.
    3. Untuk setiap bidang kelas yang diurutkan berdasarkan nama bidang (kecuali bidang transien statis dan privat pribadi: Nama bidang. Pengubah bidang ditulis sebagai integer 32-bit. Deskriptor bidang.
    4. Jika inisialisasi kelas ada, tuliskan yang berikut: Nama metode,.
    5. Pengubah metode, java.lang.reflect.Modifier.STATIC, ditulis sebagai integer 32-bit.
    6. Penjelasan metode, () V.
    7. Untuk setiap konstruktor non-pribadi diurutkan berdasarkan nama metode dan tanda tangan: Nama metode,. Pengubah metode ditulis sebagai integer 32-bit. Penjelasan metode ini.
    8. Untuk setiap metode non-pribadi diurutkan berdasarkan nama metode dan tanda tangan: Nama metode. Pengubah metode ditulis sebagai integer 32-bit. Penjelasan metode ini.
    9. Algoritma SHA-1 dieksekusi pada aliran byte yang dihasilkan oleh DataOutputStream dan menghasilkan lima nilai 32-bit sha [0..4]. Nilai hash dikumpulkan dari nilai 32-bit pertama dan kedua dari intisari pesan SHA-1. Jika hasil dari message digest, lima kata 32-bit H0 H1 H2 H3 H4, berada dalam array lima nilai int bernama sha, nilai hash akan dihitung sebagai berikut:
    long hash = ((sha[0] >>> 24) & 0xFF) |
>            ((sha[0] >>> 16) & 0xFF) << 8 |
>            ((sha[0] >>> 8) & 0xFF) << 16 |
>            ((sha[0] >>> 0) & 0xFF) << 24 |
>            ((sha[1] >>> 24) & 0xFF) << 32 |
>            ((sha[1] >>> 16) & 0xFF) << 40 |
>            ((sha[1] >>> 8) & 0xFF) << 48 |
>        ((sha[1] >>> 0) & 0xFF) << 56;

Algoritma serialisasi Java

Algoritma untuk cerita bersambung suatu objek dijelaskan sebagai berikut:
1. Ia menulis metadata dari kelas yang terkait dengan sebuah instance.
2. Secara rekursif menulis deskripsi superclass sampai menemukan java.lang.object .
3. Setelah selesai menulis informasi metadata, itu kemudian mulai dengan data aktual yang terkait dengan instance. Tapi kali ini, itu dimulai dari superclass paling atas.
4. Secara rekursif menulis data yang terkait dengan instance, mulai dari superclass ke kelas yang paling diturunkan.

Hal-hal yang Perlu Diingat:

  1. Bidang statis di kelas tidak dapat diserialisasi.

    public class A implements Serializable{
         String s;
         static String staticString = "I won't be serializable";
    }
  2. Jika serialversionuid berbeda di kelas baca itu akan mengeluarkan InvalidClassExceptionpengecualian.

  3. Jika suatu kelas mengimplementasikan serializable maka semua sub kelasnya juga akan serializable.

    public class A implements Serializable {....};
    
    public class B extends A{...} //also Serializable
  4. Jika suatu kelas memiliki referensi dari kelas lain, semua referensi harus Serializable jika tidak proses serialisasi tidak akan dilakukan. Dalam kasus seperti itu, NotSerializableException dilemparkan pada saat runtime.

Misalnya:

public class B{
     String s,
     A a; // class A needs to be serializable i.e. it must implement Serializable
}
Pritam Banerjee
sumber
1
'Serialisasi adalah proses serialisasi keadaan objek diwakili dan disimpan dalam bentuk urutan byte' tidak ada artinya. Jika serialVersionUIDberbeda itu akan melempar InvalidClassException, bukan a ClassCastException. Tidak perlu menyia-nyiakan semua ruang yang merespek serialVersionUIDperhitungan. Dokumentasi dikutip, terlalu panjang, tetapi tidak terkait atau dikutip dengan benar. Terlalu banyak bulu di sini dan terlalu banyak kesalahan.
Marquis of Lorne
'Serialisasi adalah proses serialisasi' tetap tidak berarti.
Marquis of Lorne
6

Serialisasi adalah proses mengubah status objek menjadi bit sehingga dapat disimpan pada hard drive. Saat Anda menghapus objek yang sama, objek itu akan mempertahankan kondisinya nanti. Ini memungkinkan Anda membuat ulang objek tanpa harus menyimpan properti objek dengan tangan.

http://en.wikipedia.org/wiki/Serialization

Keju Daneish
sumber
"... sehingga dapat disimpan di hard drive." Atau ditransfer melalui protokol biner.
Jim Anderson
4

Serialisasi Java Object

masukkan deskripsi gambar di sini

Serializationadalah mekanisme untuk mengubah grafik objek Java menjadi array byte untuk penyimpanan ( to disk file) atau transmisi ( across a network), maka dengan menggunakan deserialisasi kita dapat mengembalikan grafik objek. Grafik objek dipulihkan dengan benar menggunakan mekanisme berbagi referensi. Tetapi sebelum menyimpan, periksa apakah serialVersionUID dari input-file / jaringan dan .class file serialVersionUID adalah sama. Jika tidak, lempar a java.io.InvalidClassException.

Setiap kelas versi harus mengidentifikasi versi kelas asli yang dapat digunakan untuk menulis stream dan dari mana ia dapat membaca. Misalnya, kelas berversi harus mendeklarasikan:

Sintaks serialVersionUID

// ANY-ACCESS-MODIFIER static final long serialVersionUID = (64-bit has)L;
private static final long serialVersionUID = 3487495895819393L;

serialVersionUID sangat penting untuk proses serialisasi. Tapi itu opsional bagi pengembang untuk menambahkannya ke file sumber java. Jika serialVersionUID tidak termasuk, runtime serialisasi akan menghasilkan serialVersionUID dan mengaitkannya dengan kelas. Objek berseri akan berisi serialVersionUID ini bersama dengan data lainnya.

Catatan - Sangat disarankan bahwa semua kelas serializable secara eksplisit mendeklarasikan serialVersionUID since the default serialVersionUID computation is highly sensitive to class details that may vary depending on compiler implementations,, dan dengan demikian dapat mengakibatkan konflik serialVersionUID yang tidak terduga selama deserialisasi, yang menyebabkan deserialisasi gagal.

Memeriksa Kelas Serializable

masukkan deskripsi gambar di sini


Objek Java hanya bisa serial. jika suatu kelas atau salah satu dari superclasses mengimplementasikan antarmuka java.io.Serializable atau subinterface-nya, java.io.Externalizable .

  • Sebuah kelas harus mengimplementasikan antarmuka java.io.Serializable agar serialisasi objeknya berhasil. Serializable adalah antarmuka marker dan digunakan untuk memberi tahu kompiler bahwa kelas yang mengimplementasikannya harus ditambahkan perilaku serializable. Di sini Java Virtual Machine (JVM) bertanggung jawab atas serialisasi otomatisnya.

    Kata kunci sementara: java.io.Serializable interface

    Saat membuat serial suatu objek, jika kita tidak ingin anggota data tertentu dari objek menjadi serial, kita dapat menggunakan pengubah sementara. Kata kunci sementara akan mencegah anggota data tersebut untuk diserialisasi.

    • Bidang yang dinyatakan sebagai sementara atau statis diabaikan oleh proses serialisasi.

    TRANSIEN & VOLATILE

    +--------------+--------+-------------------------------------+
    |  Flag Name   |  Value | Interpretation                      |
    +--------------+--------+-------------------------------------+
    | ACC_VOLATILE | 0x0040 | Declared volatile; cannot be cached.|
    +--------------+--------+-------------------------------------+
    |ACC_TRANSIENT | 0x0080 | Declared transient; not written or  |
    |              |        | read by a persistent object manager.|
    +--------------+--------+-------------------------------------+
    class Employee implements Serializable {
        private static final long serialVersionUID = 2L;
        static int id;
    
        int eno; 
        String name;
        transient String password; // Using transient keyword means its not going to be Serialized.
    }
  • Menerapkan antarmuka Externalizable memungkinkan objek untuk mengambil kendali penuh atas konten dan format bentuk serial objek. Metode antarmuka Externalizable, writeExternal dan readExternal, dipanggil untuk menyimpan dan mengembalikan keadaan objek. Ketika diimplementasikan oleh kelas mereka dapat menulis dan membaca keadaan mereka sendiri menggunakan semua metode ObjectOutput dan ObjectInput. Merupakan tanggung jawab objek untuk menangani versi apa pun yang terjadi.

    class Emp implements Externalizable {
        int eno; 
        String name;
        transient String password; // No use of transient, we need to take care of write and read.
    
        @Override
        public void writeExternal(ObjectOutput out) throws IOException {
            out.writeInt(eno);
            out.writeUTF(name);
            //out.writeUTF(password);
        }
        @Override
        public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
            this.eno = in.readInt();
            this.name = in.readUTF();
            //this.password = in.readUTF(); // java.io.EOFException
        }
    }
  • Hanya objek yang mendukung antarmuka java.io.Serializable atau java.io.Externalizable yang dapat written to/read from stream. Kelas dari setiap objek serializable dikodekan termasuk nama kelas dan tanda tangan kelas, nilai-nilai bidang dan array objek, dan penutupan objek lain yang dirujuk dari objek awal.

Contoh Serializable Untuk File

public class SerializationDemo {
    static String fileName = "D:/serializable_file.ser";

    public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException {
        Employee emp = new Employee( );
        Employee.id = 1; // Can not Serialize Class data.
        emp.eno = 77;
        emp.name = "Yash";
        emp.password = "confidential";
        objects_WriteRead(emp, fileName);

        Emp e = new Emp( );
        e.eno = 77;
        e.name = "Yash";
        e.password = "confidential";
        objects_WriteRead_External(e, fileName);

        /*String stubHost = "127.0.0.1";
        Integer anyFreePort = 7777;
        socketRead(anyFreePort); //Thread1
        socketWrite(emp, stubHost, anyFreePort); //Thread2*/

    }
    public static void objects_WriteRead( Employee obj, String serFilename ) throws IOException{
        FileOutputStream fos = new FileOutputStream( new File( serFilename ) );
        ObjectOutputStream objectOut = new ObjectOutputStream( fos );
        objectOut.writeObject( obj );
        objectOut.close();
        fos.close();

        System.out.println("Data Stored in to a file");

        try {
            FileInputStream fis = new FileInputStream( new File( serFilename ) );
            ObjectInputStream ois = new ObjectInputStream( fis );
            Object readObject;
            readObject = ois.readObject();
            String calssName = readObject.getClass().getName();
            System.out.println("Restoring Class Name : "+ calssName); // InvalidClassException

            Employee emp = (Employee) readObject;
            System.out.format("Obj[No:%s, Name:%s, Pass:%s]", emp.eno, emp.name, emp.password);

            ois.close();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
    public static void objects_WriteRead_External( Emp obj, String serFilename ) throws IOException {
        FileOutputStream fos = new FileOutputStream(new File( serFilename ));
        ObjectOutputStream objectOut = new ObjectOutputStream( fos );

        obj.writeExternal( objectOut );
        objectOut.flush();

        fos.close();

        System.out.println("Data Stored in to a file");

        try {
            // create a new instance and read the assign the contents from stream.
            Emp emp = new Emp();

            FileInputStream fis = new FileInputStream(new File( serFilename ));
            ObjectInputStream ois = new ObjectInputStream( fis );

            emp.readExternal(ois);

            System.out.format("Obj[No:%s, Name:%s, Pass:%s]", emp.eno, emp.name, emp.password);

            ois.close();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

Contoh Serializable Melalui Jaringan

Mendistribusikan keadaan objek di ruang alamat yang berbeda, baik dalam proses yang berbeda di komputer yang sama, atau bahkan di beberapa komputer yang terhubung melalui jaringan, tetapi bekerja bersama dengan berbagi data dan menggunakan metode.

/**
 * Creates a stream socket and connects it to the specified port number on the named host. 
 */
public static void socketWrite(Employee objectToSend, String stubHost, Integer anyFreePort) {
    try { // CLIENT - Stub[marshalling]
        Socket client = new Socket(stubHost, anyFreePort);
        ObjectOutputStream out = new ObjectOutputStream(client.getOutputStream());
        out.writeObject(objectToSend);
        out.flush();
        client.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}
// Creates a server socket, bound to the specified port. 
public static void socketRead(  Integer anyFreePort ) {
    try { // SERVER - Stub[unmarshalling ]
        ServerSocket serverSocket = new ServerSocket( anyFreePort );
        System.out.println("Server serves on port and waiting for a client to communicate");
            /*System.in.read();
            System.in.read();*/

        Socket socket = serverSocket.accept();
        System.out.println("Client request to communicate on port server accepts it.");

        ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
        Employee objectReceived = (Employee) in.readObject();
        System.out.println("Server Obj : "+ objectReceived.name );

        socket.close();
        serverSocket.close();
    } catch (IOException | ClassNotFoundException e) {
        e.printStackTrace();
    }
}

@Lihat

Yash
sumber
1
Saat Anda menambahkan jawaban ke pertanyaan berusia enam tahun yang sudah memiliki beberapa jawaban yang sangat bagus, Anda harus melakukan jauh lebih baik daripada hiruk-pikuk kesalahan ejaan.
Marquis of Lorne
@ejp Downvoting adalah alat untuk mengekspresikan pendapat negatif Anda. Menjadi ofensif dan kasar batas tidak dapat diterima.
Konstantinos Chertouras
1
@KonstantinosChertouras Memberi alasan untuk downvote sangat membantu poster, dan itulah alasan saya, suka atau tidak seperti yang Anda mau.
Marquis of Lorne
Anda juga perlu menghindari kesalahan seperti menyatakan bahwa serialisasi memiliki tujuan keamanan. Tidak.
Marquis of Lorne
@ EJP Saya telah memperbarui posting saya, mengoreksi bahwa Serialisasi tidak untuk tujuan keamanan, tetapi digunakan untuk mengubah keadaan Objek ke Penyimpanan apa pun dan untuk mendapatkan keadaan asli objek kembali menggunakan SUID melalui deserializing mechanisum. JVM to JVM
Yash
3

Serialisasi adalah proses menyimpan suatu objek dalam media penyimpanan (seperti file, atau buffer memori) atau mengirimkannya melalui koneksi jaringan dalam bentuk biner. Objek berseri adalah JVM independen dan dapat diserialisasi ulang oleh JVM apa pun. Dalam hal ini status objek java "dalam memori" dikonversi menjadi aliran byte. Jenis file ini tidak dapat dipahami oleh pengguna. Ini adalah jenis objek khusus yaitu digunakan kembali oleh JVM (Java Virtual Machine). Proses serialisasi objek ini juga disebut deflating atau mengatur objek.

Objek yang akan diserialisasi harus mengimplementasikan java.io.SerializableAntarmuka. Mekanisme serialisasi default untuk objek menulis kelas objek, tanda tangan kelas, dan nilai semua bidang non-transien dan non-statis.

class ObjectOutputStream extends java.io.OutputStream implements ObjectOutput,

ObjectOutputantarmuka memperluas DataOutputantarmuka dan menambahkan metode untuk serialisasi objek dan menulis byte ke file. The ObjectOutputStreammeluas java.io.OutputStreamdan alat ObjectOutput antarmuka. Ini cerita bersambung objek, array, dan nilai-nilai lain ke aliran. Jadi konstruktor ObjectOutputStreamditulis sebagai:

ObjectOutput ObjOut = new ObjectOutputStream(new FileOutputStream(f));

Kode di atas telah digunakan untuk membuat turunan ObjectOutputkelas dengan ObjectOutputStream( )konstruktor yang menjadikan turunan FileOuputStreamsebagai parameter.

The ObjectOutputantarmuka digunakan dengan menerapkan ObjectOutputStreamkelas. Ini ObjectOutputStreamdibangun untuk membuat serial objek.

Deserializing Obyek di java

Operasi berlawanan dari serialisasi disebut deserialisasi yaitu untuk mengekstrak data dari serangkaian byte yang dikenal sebagai deserialisasi yang juga disebut menggembungkan atau unmarshalling.

ObjectInputStreammemperluas java.io.InputStreamdan mengimplementasikan ObjectInput antarmuka. Ini menghilangkan objek, array, dan nilai-nilai lainnya dari aliran input. Jadi konstruktor ObjectInputStreamditulis sebagai:

ObjectInputStream obj = new ObjectInputStream(new FileInputStream(f));

Kode di atas program menciptakan turunan dari ObjectInputStreamkelas untuk deserialize file yang telah diserialisasi oleh ObjectInputStreamkelas. Kode di atas membuat instance menggunakan instance dari FileInputStreamkelas yang menampung objek file yang ditentukan yang harus di-deserialisasi karena ObjectInputStream()konstruktor memerlukan input stream.

Sindu
sumber
2

Kembalikan file sebagai Obyek: http://www.tutorialspoint.com/java/java_serialization.htm

        import java.io.*;

        public class SerializeDemo
        {
           public static void main(String [] args)
           {
              Employee e = new Employee();
              e.name = "Reyan Ali";
              e.address = "Phokka Kuan, Ambehta Peer";
              e.SSN = 11122333;
              e.number = 101;

              try
              {
                 FileOutputStream fileOut =
                 new FileOutputStream("/tmp/employee.ser");
                 ObjectOutputStream out = new ObjectOutputStream(fileOut);
                 out.writeObject(e);
                 out.close();
                 fileOut.close();
                 System.out.printf("Serialized data is saved in /tmp/employee.ser");
              }catch(IOException i)
              {
                  i.printStackTrace();
              }
           }
        }

    import java.io.*;
    public class DeserializeDemo
    {
       public static void main(String [] args)
       {
          Employee e = null;
          try
          {
             FileInputStream fileIn = new FileInputStream("/tmp/employee.ser");
             ObjectInputStream in = new ObjectInputStream(fileIn);
             e = (Employee) in.readObject();
             in.close();
             fileIn.close();
          }catch(IOException i)
          {
             i.printStackTrace();
             return;
          }catch(ClassNotFoundException c)
          {
             System.out.println("Employee class not found");
             c.printStackTrace();
             return;
          }
          System.out.println("Deserialized Employee...");
          System.out.println("Name: " + e.name);
          System.out.println("Address: " + e.address);
          System.out.println("SSN: " + e.SSN);
          System.out.println("Number: " + e.number);
        }
    }
Ran Adler
sumber
Ini tidak menjawab bagian 'apa itu' atau 'tolong jelaskan' dari pertanyaan itu.
Marquis of Lorne
1

| * | Serialisasi kelas: Mengubah objek menjadi byte dan byte kembali ke objek (Deserialisasi).

class NamCls implements Serializable
{
    int NumVar;
    String NamVar;
}

| => Obyek-Serialisasi adalah proses mengubah keadaan suatu objek menjadi uap byte.

  • | -> Terapkan ketika Anda ingin objek ada di luar masa pakai JVM.
  • | -> Obyek berseri dapat disimpan dalam Database.
  • | -> Serializable-objek tidak dapat dibaca dan dipahami oleh manusia sehingga kita dapat mencapai keamanan.

| => Object-Deserialization adalah proses mendapatkan keadaan objek dan menyimpannya ke objek (java.lang.Object).

  • | -> Sebelum menyimpan statusnya, periksa apakah file-file / jaringan serialVersionUID dan file .class serialVersionUID sama.
    & nbsp & nbspJika tidak membuang java.io.InvalidClassException.

| => Objek Java hanya bisa serial, jika kelasnya atau superclasses-nya

  • mengimplementasikan antarmuka java.io.Serializable atau
  • subinterface-nya, java.io.Externalizable.

| => Bidang statis di kelas tidak dapat diserialisasi.

class NamCls implements Serializable
{
    int NumVar;
    static String NamVar = "I won't be serializable";;
}

| => Jika Anda tidak ingin membuat serial suatu variabel dari suatu kelas, gunakan kata kunci sementara

class NamCls implements Serializable
{
    int NumVar;
    transient String NamVar;
}

| => Jika suatu kelas mengimplementasikan serializable maka semua sub kelasnya juga akan serializable.

| => Jika suatu kelas memiliki referensi dari kelas lain, semua referensi harus Serializable jika tidak proses serialisasi tidak akan dilakukan. Dalam kasus seperti itu,
NotSerializableException dilemparkan pada saat runtime.

Sujay UN
sumber
0

Saya akan menawarkan analogi untuk berpotensi membantu dalam memperkuat tujuan konseptual / kepraktisan serialisasi objek / deserialisasi .

Saya membayangkan serialisasi objek / deserialisasi dalam konteks upaya untuk memindahkan objek melalui saluran badai. Objek ini pada dasarnya "terurai" atau serial ke versi yang lebih modular dari dirinya sendiri - dalam hal ini, serangkaian byte - untuk secara efektif diberikan bagian melalui media. Dalam pengertian komputasi, kita bisa melihat jalur yang ditempuh oleh byte melalui drain badai sama dengan byte yang bepergian melalui jaringan. Kami mentransmutasikan objek kami untuk menyesuaikan dengan moda transportasi, atau format yang lebih diinginkan. Objek serial biasanya akan disimpan dalam file biner yang nantinya dapat dibaca dari, ditulis untuk, atau keduanya.

Mungkin begitu objek kita dapat menyelinap melalui saluran sebagai serangkaian byte yang terurai, kita mungkin ingin menyimpan representasi objek tersebut sebagai data biner di dalam basis data atau hard disk drive. Namun takeaway utama, adalah bahwa dengan serialisasi / deserialisasi, kita memiliki opsi untuk membiarkan objek kita tetap dalam bentuk biner setelah serial, atau "mengambil" bentuk asli objek dengan melakukan deserialisasi.

Benjamin Westburg
sumber