Pada artikel ini kami akan menjelaskan apa itu serialisasi dan cara kerjanya di Java.
Gambar 1. Representasi grafis dari Threads
Aliran pada dasarnya dibagi menjadi dua jenis:
Perkenalan
Serialisasi objek adalah kemampuan suatu objek untuk menyimpan salinan lengkap dirinya dan objek lain yang direferensikannya menggunakan aliran keluaran (misalnya, ke file eksternal). Dengan cara ini, objek dapat dibuat ulang dari salinan serial (disimpan) nanti bila diperlukan. Serialisasi objek, fitur baru yang diperkenalkan di JDK 1.1, menyediakan fungsi untuk mengonversi grup atau objek individual, menjadi bitstream atau array byte, untuk penyimpanan atau transmisi melalui jaringan. Dan seperti yang dinyatakan, aliran bit atau array byte tertentu dapat diubah kembali menjadi objek Java. Hal ini terutama terjadi secara otomatis berkatObjectInputStream
dan kelas ObjectOutputStream
. Pemrogram dapat memutuskan untuk mengimplementasikan fungsi ini dengan mengimplementasikan antarmuka Serializable
saat membuat kelas. Proses serialisasi juga dikenal sebagai objek marshaling , sedangkan deserialisasi dikenal sebagai unmarshaling . Serialisasi adalah mekanisme yang memungkinkan suatu objek menyimpan salinan dirinya dan semua objek lain yang direferensikan oleh objek tersebut ke file eksternal menggunakan ekstensi ObjectOutputStream
. Objek yang disimpan dapat berupa struktur data, diagram, objek kelas JFrame
, atau objek lainnya, apa pun tipenya. Pada saat yang sama, serialisasi menyimpan informasi tentang jenis suatu objek sehingga nanti, ketika dideserialisasi, informasi tersebut digunakan untuk membuat ulang jenis objek yang sebenarnya. Jadi, serialisasi memberikan kemampuan berikut:
- Sebuah sistem untuk menyimpan objek, yaitu: menyimpan propertinya ke file eksternal, ke disk, atau ke database.
- Sistem panggilan prosedur jarak jauh.
- Sistem distribusi objek misalnya pada komponen perangkat lunak seperti COM, COBRA.
- Sistem untuk mengidentifikasi perubahan data variabel dari waktu ke waktu.
Aliran:
Setiap program harus menulis datanya ke lokasi penyimpanan atau pipa, dan setiap program harus membaca data dari pipa atau lokasi penyimpanan. Di Java, saluran tempat program menulis dan dari mana program membaca data disebut Streams (Stream
) .
- Kelas aliran byte yang disebut *Streaming
- Kelas aliran karakter disebut *Pembaca dan *Penulis
Kegigihan
Persistensi objek adalah kemampuan suatu objek untuk hidup atau dengan kata lain “bertahan” dalam eksekusi suatu program. Ini berarti bahwa objek apa pun yang dibuat saat runtime akan dimusnahkan oleh pemulung JVM setiap kali objek tersebut tidak lagi digunakan. Namun jika API persistensi diimplementasikan, objek-objek ini tidak akan dimusnahkan oleh pemulung JVM, melainkan akan diizinkan untuk "hidup", yang juga memungkinkan untuk mengaksesnya saat aplikasi diluncurkan lagi. Dengan kata lain, persistensi berarti ada masa hidup suatu objek, tidak bergantung pada masa hidup aplikasi yang sedang berjalan. Salah satu cara untuk menerapkan persistensi adalah dengan menyimpan objek di suatu tempat di file atau database eksternal, lalu memulihkannya di lain waktu menggunakan file atau database tersebut sebagai sumber. Di sinilah serialisasi berperan. Objek non-persisten apa pun tetap ada selama JVM berjalan. Objek berseri hanyalah objek yang diubah menjadi aliran, yang kemudian disimpan ke file eksternal atau ditransfer melalui jaringan untuk penyimpanan dan pemulihan.Implementasi antarmuka Serializable
Setiap kelas harus mengimplementasikan antarmukajava.io.Serializable
untuk membuat serialisasi objek kelas tersebut. Antarmuka Serializable
tidak memiliki metode dan hanya menandai kelas sehingga dapat diidentifikasi sebagai dapat diserialkan. Hanya bidang objek kelas berseri yang dapat disimpan. Metode atau konstruktor tidak disimpan sebagai bagian dari aliran serial. Jika suatu objek bertindak sebagai referensi ke objek lain, maka bidang objek tersebut juga akan diserialkan jika kelas objek tersebut mengimplementasikan interface Serializable
. Dengan kata lain, grafik objek yang diperoleh ini sepenuhnya dapat diserialkan. Grafik objek mencakup pohon atau struktur bidang suatu objek dan subobjeknya. Dua kelas utama yang membantu mengimplementasikan antarmuka Seriliazable
:
ObjectInputStream
ObjectOutputStream
import java.io.*;
public class RandomClass implements Serializable {
// Генерация рандомного значения
private static int r() {
return (int)(Math.random() * 10);
}
private int data[];
// Конструктор
public RandomClass() {
datafile = new int[r()];
for (int i=0; i<datafile.length; i++)
datafile[i]=r();
}
public void printout() {
System.out.println("This RandomClass has "+datafile.length+" random integers");
for (int i=0; i<datafile.length; i++) {
System.out.print(datafile[i]+":");
System.out.println();
}
}
Dalam kode di atas, sebuah kelas dibuat yang dapat diserialkan karena "ditandai" oleh antarmuka serialisasi. Kelas membuat array bilangan bulat acak ketika sebuah instance dibuat. Kode di bawah ini menunjukkan kemampuan untuk menulis objek ke aliran menggunakan ekstensi ObjectOutputStream
. Program ini memiliki array bilangan bulat, tetapi untuk serialisasi kita tidak perlu melakukan iterasi pada objek internalnya. Antarmuka Seriliazable
menangani hal ini secara otomatis. Listing 2. Contoh sederhana serialisasi objek untuk output ke file
import java.io.*;
import java.util.*;
public class OutSerialize {
public static void main (String args[]) throws IOException {
RandomClass rc1 = new RandomClass();
RandomClass rc2 = new RandomClass();
//создание цепи потоков с потоком вывода an object в конце
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("objects.dat"));
Date now = new Date(System.currentTimeMillis());
//java.util.* был импортирован для использования класса Date
out.writeObject(now);
out.writeObject(rc1);
out.writeObject(rc2);
out.close();
System.out.println("I have written:");
System.out.println("A Date object: "+now);
System.out.println("Two Group of randoms");
rc1.printout();
rc2.printout();
}
}
Kode di bawah ini menunjukkan kemampuan kelas ObjectInputStream
, yang membaca data serial dari file eksternal ke dalam program. Perhatikan bahwa objek dibaca dalam urutan yang sama dengan saat objek tersebut ditulis ke file. Listing 3. Membaca objek berseri atau Deserialisasi
import java.io.*;
import java.util.*;
public class InSerialize {
public static void main (String args[]) throws IOException, ClassNotFoundException {
ObjectInputStream in = new ObjectInputStream (new FileInputStream("objects.dat"));
Date d1 = (Date)in.readObject();
RandomClass rc1 = (RandomClass)in.readObject();
RandomClass rc2 = (RandomClass)in.readObject();
System.out.println("I have read:");
System.out.println("A Date object: "+d1);
System.out.println("Two Group of randoms");
rc1.printout();
rc2.printout();
}
}
Hampir semua kelas Java dapat diserialkan, termasuk kelas AWT. Sebuah bingkai, yang merupakan jendela, berisi sekumpulan komponen grafis. Jika frame diserialkan, mesin serialisasi akan menangani hal ini dan membuat serialisasi semua komponen dan datanya (posisi, konten, dll.). Beberapa objek kelas Java tidak dapat dibuat serial karena berisi data yang mereferensikan sumber daya sistem operasi sementara. Misalnya kelas java.io.FileInputStream
dan java.lang.Thread
. Jika suatu objek berisi referensi ke elemen yang tidak dapat diserialkan, seluruh operasi serialisasi akan gagal dan pengecualian akan dilempar NotSerializableException
. Jika ada objek yang mengacu pada referensi objek yang tidak berseri, maka objek tersebut dapat diserialkan menggunakan kata kunci transient . Listing 4. Membuat objek serializable menggunakan kata kunci transient
public class Sclass implements Serializable{
public transient Thread newThread;
//помните, что поток(поток параллельного исполнения) по умолчанию не сериализуемый класс
private String studentID;
private int sum;
}
Keamanan dalam Serialisasi
Membuat serial kelas di Java melibatkan penerusan semua datanya ke file eksternal atau database melalui aliran. Kita bisa membatasi data yang akan diserialkan kapan pun kita mau. Ada dua cara untuk melakukan ini:- Setiap parameter kelas yang dideklarasikan sebagai transient tidak diserialkan (secara default, semua parameter kelas diserialkan)
- Atau, setiap parameter kelas yang ingin kita serialkan ditandai dengan tag
Externalizable
(secara default, tidak ada parameter yang diserialkan).
ObjectOutputStream
, ketika dipanggil pada suatu objek, jika bidang data objek tersebut ditandai transient . Misalnya: private transient String password
. Di sisi lain, untuk mendeklarasikan data suatu objek secara eksplisit sebagai serializable, kita harus menandai kelas tersebut sebagai kelas yang ExternalizablewriteExternal
secara eksplisit readExteranl
menulis dan membaca data objek tersebut.
Kesimpulan
Fitur serialisasi objek digunakan di banyak sistem terdistribusi sebagai cara untuk mentransfer data. Namun serialisasi mengungkap detail tersembunyi, sehingga menghancurkan keaslian tipe data abstrak, yang pada gilirannya menghancurkan enkapsulasi. Pada saat yang sama, menyenangkan mengetahui bahwa data objek serial adalah data yang sama dengan objek asli dan asli. Ini juga merupakan peluang bagus untuk mengimplementasikan antarmukaObjectInputValidation
dan mengganti metode validateObject()
, meskipun beberapa baris kode digunakan. Jika objek tidak ditemukan, maka kita dapat memberikan pengecualian dengan tepat InvalidObjectException
. Artikel asli: Cara kerja serialisasi di Java
GO TO FULL VERSION