Serializable
iya proyek, lan apa ora tresna marang implementasine otomatis saka kabèh proses? Lan conto sing kita deleng uga ora rumit. Dadi apa masalahe? Napa kita butuh antarmuka liyane kanggo tugas sing padha? Kasunyatane ana Serializable
sawetara kekurangan. We dhaptar sawetara saka wong-wong mau:
-
Kinerja. Antarmuka
Serializable
wis akeh kaluwihan, nanging kinerja dhuwur cetha ora siji saka wong-wong mau.First,
Serializable
's implementasine internal ngasilake jumlah gedhe saka informasi layanan lan kabeh limo data sauntara.Kapindho,
Serializable
gumantung ing API Refleksi (sampeyan ora kudu nyilem jero babagan iki saiki; sampeyan bisa maca liyane ing wektu luang, yen sampeyan kasengsem). Iki ngidini sampeyan nindakake perkara-perkara sing katon ora mungkin ing Jawa: contone, ngganti nilai kolom pribadi. CodeGym duwe artikel sing apik babagan Reflection API . Sampeyan bisa maca babagan ana. -
Fleksibilitas. Kita ora ngontrol proses serialisasi-deserialisasi nalika nggunakake antarmuka
Serializable
.Siji-sijine, trep banget, amarga yen kita ora prihatin babagan kinerja, mula katon apik yen ora kudu nulis kode. Nanging apa yen kita pancene kudu nambah sawetara fitur kita dhewe (kita bakal nyedhiyani conto ing ngisor iki) kanggo logika serialization?
Sejatine, kabeh kita kudu ngontrol proses kasebut yaiku
transient
tembung kunci kanggo ngilangi sawetara data. Mekaten. Iku kabeh toolbox kita :/ -
Keamanan. Item iki asale saka bagean sadurunge.
Kita wis ora nglampahi akeh wektu mikir bab iki sadurunge, nanging apa yen sawetara informasi ing kelas sampeyan ora dimaksudaké kanggo prying mripat lan kuping wong liya? Conto prasaja yaiku tembung sandhi utawa data pangguna pribadhi liyane, sing ing jaman saiki diatur dening pirang-pirang undang-undang.
Yen kita nggunakake
Serializable
, kita ora bisa nindakake apa-apa. We serialize kabeh minangka iku.Nanging yen kita nindakake kanthi bener, kita kudu ngenkripsi data kaya iki sadurunge nulis menyang file utawa ngirim liwat jaringan. Nanging
Serializable
ora nggawe iki bisa.

Externalizable
.
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
public class UserInfo implements Externalizable {
private String firstName;
private String lastName;
private String superSecretInformation;
private static final long SERIAL_VERSION_UID = 1L;
// ...constructor, getters, setters, toString()...
@Override
public void writeExternal(ObjectOutput out) throws IOException {
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
}
}
Nalika sampeyan bisa ndeleng, kita duwe owah-owahan sing signifikan! Sing utama jelas: nalika ngetrapake antarmuka Externalizable
, sampeyan kudu ngetrapake rong cara sing dibutuhake: writeExternal()
lanreadExternal()
. Kaya sing wis dakkandhakake sadurunge, tanggung jawab kanggo serialisasi lan deserialization bakal ana ing programmer. Nanging saiki sampeyan bisa ngatasi masalah ora bisa ngontrol proses kasebut! Kabeh proses diprogram langsung dening sampeyan. Alami, iki ngidini mekanisme sing luwih fleksibel. Kajaba iku, masalah keamanan wis ditanggulangi. Kaya sing sampeyan ngerteni, kelas kita duwe lapangan data pribadhi sing ora bisa disimpen tanpa enkripsi. Saiki kita bisa kanthi gampang nulis kode sing nyukupi kendala iki. Contone, kita bisa nambah kanggo kelas kita loro cara pribadi prasaja kanggo encrypt lan decrypt data sensitif. Kita bakal nulis data menyang file lan maca saka file ing wangun ndhelik. Data liyane bakal ditulis lan diwaca kaya apa wae :) Akibate, kelas kita katon kaya iki:
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.Base64;
public class UserInfo implements Externalizable {
private String firstName;
private String lastName;
private String superSecretInformation;
private static final long serialVersionUID = 1L;
public UserInfo() {
}
public UserInfo(String firstName, String lastName, String superSecretInformation) {
this.firstName = firstName;
this.lastName = lastName;
this.superSecretInformation = superSecretInformation;
}
@Override
public void writeExternal(ObjectOutput out) throws IOException {
out.writeObject(this.getFirstName());
out.writeObject(this.getLastName());
out.writeObject(this.encryptString(this.getSuperSecretInformation()));
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
firstName = (String) in.readObject();
lastName = (String) in.readObject();
superSecretInformation = this.decryptString((String) in.readObject());
}
private String encryptString(String data) {
String encryptedData = Base64.getEncoder().encodeToString(data.getBytes());
System.out.println(encryptedData);
return encryptedData;
}
private String decryptString(String data) {
String decrypted = new String(Base64.getDecoder().decode(data));
System.out.println(decrypted);
return decrypted;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public String getSuperSecretInformation() {
return superSecretInformation;
}
}
Kita ngleksanakake rong cara sing nggunakake padha ObjectOutput
lan ObjectInput
paramèter sing wis ketemu ing pawulangan bab Serializable
. Ing wektu sing tepat, kita ndhelik utawa dekripsi data sing dibutuhake, lan nggunakake data sing dienkripsi kanggo nggawe serialisasi obyek kita. Ayo ndeleng carane iki katon ing laku:
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException, ClassNotFoundException {
FileOutputStream fileOutputStream = new FileOutputStream("C:\\Users\\Username\\Desktop\\save.ser");
ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
UserInfo userInfo = new UserInfo("Paul", "Piper", "Paul Piper's passport data");
objectOutputStream.writeObject(userInfo);
objectOutputStream.close();
}
}
Ing encryptString()
lan decryptString()
cara, kita khusus ditambahaké console output kanggo verifikasi wangun kang data rahasia bakal ditulis lan diwaca. Kode ing ndhuwur nampilake baris ing ngisor iki: SXZhbiBJdmFub3YncyBwYXNzcG9ydCBkYXRh Enkripsi kasil! Isi lengkap berkas katon kaya mangkene: ¬н sr UserInfoГ!}ҐџC‚ћ xpt Ivant Ivanovt $SXZhbiBJdmFub3YncyBwYXNzcG9ydCBkYXRhx Saiki ayo nyoba nggunakake logika deseralisasi.
public class Main {
public static void main(String[] args) throws IOException, ClassNotFoundException {
FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Username\\Desktop\\save.ser");
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
UserInfo userInfo = (UserInfo) objectInputStream.readObject();
System.out.println(userInfo);
objectInputStream.close();
}
}
Ya, ora ana sing rumit ing kene. Iku kudu bisa! Kita mbukak lan njaluk ... Pangecualian ing thread "utama" java.io.InvalidClassException: UserInfo; ora ana konstruktor sing bener 
Serializable
kita entuk tanpa siji ... : / Kene kita wis ketemu nuansa penting liyane. prabédan antarane Serializable
lan Externalizable
dumunung ora mung ing programmer kang 'ditambahi' akses lan kemampuan kanggo luwih fleksibel ngontrol proses, nanging uga ing proses dhewe. Ndhuwur kabeh, ing mekanisme deserialization . Nalika nggunakakeSerializable
, memori mung diparengake kanggo obyek, banjur nilai diwaca saka stream lan digunakake kanggo nyetel kothak obyek. Yen kita nggunakake Serializable
, konstruktor obyek ora disebut! Kabeh karya kedadeyan liwat refleksi (API Refleksi, sing sedhela kasebut ing pawulangan pungkasan). Kanthi Externalizable
, mekanisme deserialization beda. Konstruktor standar diarani pisanan. Mung sawise iku cara UserInfo
obyek digawe readExternal()
disebut. Iku tanggung jawab kanggo nyetel lapangan obyek. Pramila kelas apa wae sing ngetrapake Externalizable
antarmuka kudu duwe konstruktor standar . Ayo tambahake siji menyang UserInfo
kelas lan mbukak kode kasebut:
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException, ClassNotFoundException {
FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Username\\Desktop\\save.ser");
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
UserInfo userInfo = (UserInfo) objectInputStream.readObject();
System.out.println(userInfo);
objectInputStream.close();
}
}
Output konsol: data paspor Paul Piper UserInfo \ firstName = 'Paul', lastName = 'Piper', superSecretInformation = 'Data paspor Paul Piper' } Saiki pancen beda! Kaping pisanan, senar dekripsi kanthi informasi rahasia ditampilake ing konsol. Banjur obyek sing mbalekake saka file ditampilake minangka senar! Dadi, kita wis sukses ngrampungake kabeh masalah :) Topik serialisasi lan deseralisasi katon gampang, nanging, kaya sing sampeyan ngerteni, pelajaran kasebut wis suwe. Lan akeh liyane sing durung kita bahas! Ana isih akeh subtleties melu nalika nggunakake saben antarmuka iki. Nanging supaya otak ora njeblug saka informasi anyar sing akeh banget, aku bakal menehi dhaptar sawetara poin sing luwih penting lan menehi link menyang maca tambahan. Dadi, apa maneh sampeyan kudu ngerti? Pisanan , sajrone serialisasi (preduli saka apa sampeyan nggunakake Serializable
utawa Externalizable
), mbayar manungsa waé kanggo static
variabel. Nalika sampeyan nggunakake Serializable
, kolom iki ora serialized ing kabeh (lan, patut, Nilai sing ora ngganti, amarga static
kolom kagungane kelas, ora obyek). Nanging nalika sampeyan nggunakakeExternalizable
, sampeyan ngontrol proses kasebut dhewe, supaya kanthi teknis sampeyan bisa nggawe serial. Nanging, kita ora nyaranake, amarga tumindak kasebut bakal nggawe akeh bug sing halus. Kapindho , sampeyan uga kudu menehi perhatian marang variabel kanthi final
modifier. Nalika sampeyan nggunakake Serializable
, lagi serialized lan deserialized minangka biasanipun, nanging nalika sampeyan nggunakake Externalizable
, iku mokal kanggo deserialize final
variabel ! Alesane gampang: kabeh final
lapangan diwiwiti nalika konstruktor standar diarani - sawise iku, nilai kasebut ora bisa diganti. Mulane, kanggo serialize obyek sing duwe final
lapangan, nggunakake serialization standar diwenehake dening Serializable
. Katelu , nalika sampeyan nggunakake warisan, kabeh kelas turunan sing marisi sawetaraExternalizable
kelas uga kudu konstruktor standar. Iki link menyang artikel sing apik babagan mekanisme serialisasi:
Nganti wektu sabanjure! :)
GO TO FULL VERSION