Serializable
Aku coped karo proyek, lan implementasine otomatis kabeh proses ora bisa nanging bungah. Conto sing kita deleng uga ora rumit. Dadi apa sing menehi hasil? Napa antarmuka liyane kanggo tugas sing padha? Kasunyatan iku Serializable
nduweni sawetara kekurangan. Ayo kita dhaptar sawetara:
-
Kinerja. Antarmuka wis
Serializable
akeh kaluwihan, nanging kinerja dhuwur cetha ora siji saka wong-wong mau.
Kaping pisanan , mekanisme internal Serializable
ngasilake akeh informasi layanan lan macem-macem jinis data sementara sajrone operasi.
Sareh (sampeyan ora kudu pindhah menyang iki saiki lan maca ing wektu luang yen kasengsem), karya Serializable
adhedhasar nggunakake API Refleksi. Contraption iki ngidini sampeyan nindakake samubarang sing katon ora mungkin ing Jawa: contone, ngganti nilai kolom pribadi. JavaRush duwe artikel sing apik babagan Reflection API , sampeyan bisa maca babagan kene.
-
Fleksibilitas. Kita ora ngontrol proses serialisasi-deserialisasi nalika nggunakake file
Serializable
.Ing tangan siji, iki trep banget, amarga yen kita ora peduli babagan kinerja, kemampuan kanggo ora nulis kode katon trep. Nanging apa yen kita pancene kudu nambah sawetara fitur kita dhewe (conto salah siji saka wong-wong mau bakal ngisor) kanggo logika serialization?
Intine, kabeh sing kudu kita kontrol proses kasebut yaiku tembung kunci
transient
kanggo ngilangi sawetara data, lan kabeh iku. Kaya "toolkit" :/ -
Safety. Titik iki sebagian nderek saka sing sadurunge.
Kita durung mikir babagan iki sadurunge, nanging kepiye yen sawetara informasi ing kelas sampeyan ora ditrapake kanggo "kuping wong liya" (luwih tepate, mata)? Conto prasaja yaiku tembung sandhi utawa data pangguna pribadhi liyane, sing ing donya modern diatur dening pirang-pirang undang-undang.
Nggunakake
Serializable
, kita ora bisa nindakake apa-apa. We serialize kabeh minangka.Nanging, kanthi cara sing apik, kita kudu ngenkripsi data kaya iki sadurunge nulis menyang file utawa ngirim liwat jaringan. Nanging
Serializable
ora menehi kesempatan iki.
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;
//...конструктор, геттеры, сеттеры, toString()...
@Override
public void writeExternal(ObjectOutput out) throws IOException {
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
}
}
Kaya sing sampeyan ngerteni, kita wis nggawe owah-owahan sing signifikan! Sing utama jelas: nalika ngetrapake antarmuka, Externalizable
sampeyan kudu ngetrapake rong cara wajib - writeExternal()
lan readExternal()
. Kaya sing wis dakkandhakake sadurunge, kabeh tanggung jawab kanggo serialisasi lan deseralisasi bakal ana ing programmer. Nanging, saiki sampeyan bisa ngatasi masalah kurang kontrol proses iki! Kabeh proses diprogram langsung dening sampeyan, sing, mesthi, nggawe mekanisme sing luwih fleksibel. Kajaba iku, masalah keamanan uga ditanggulangi. Minangka sampeyan bisa ndeleng, kita duwe lapangan ing kelas kita: data pribadhi sing ora bisa disimpen tanpa enkripsi. Saiki kita bisa kanthi gampang nulis kode sing cocog karo kendala iki. Contone, nambah rong cara pribadi prasaja kanggo kelas kita kanggo enkripsi lan decrypting data rahasia. Kita bakal nulis menyang file lan maca saka file ing wangun ndhelik. Lan kita bakal nulis lan maca data liyane minangka :) Minangka asil, kelas kita bakal 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 wis ngetrapake rong cara sing nggunakake padha ObjectOutput out
lan minangka paramèter ObjectInput
sing wis ditemoni ing kuliah babagan Serializable
. Ing wektu sing tepat, kita ndhelik utawa dekripsi data sing dibutuhake, lan ing wangun iki digunakake kanggo serialize obyek kita. Ayo ndeleng carane iki bakal 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("Ivan", "Ivanov", "Ivan Ivanov's passport data");
objectOutputStream.writeObject(userInfo);
objectOutputStream.close();
}
}
Ing encryptString()
lan cara decryptString()
, kita khusus nambah output kanggo console kanggo mriksa apa wangun data rahasia bakal ditulis lan diwaca. Kode ing ndhuwur output baris ing ngisor iki kanggo console: SXZhbiBJdmFub3YncyBwYXNzcG9ydCBkYXRh Enkripsi sukses! Isi lengkap berkas katon kaya mangkene: ¬н sr UserInfoГ!}ҐџC‚ћ xpt Ivant Ivanovt $SXZhbiBJdmFub3YncyBwYXNzcG9ydCBkYXRhx Saiki ayo nyoba nggunakake logika deseralisasi sing ditulis.
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, kayane ora ana sing rumit ing kene, mesthine bisa digunakake! Ayo mbukak ... Pangecualian ing thread "utama" java.io.InvalidClassException: UserInfo; Ora ana konstruktor sing bener Oops :( Pranyata ora dadi prasaja! Mekanisme deserialization mbuwang pangecualian lan mbutuhake kita nggawe konstruktor standar. Aku wonder apa? Serializable
Kita ngatur tanpa iku ... : / Kene kita teka menyang nuansa penting liyane Bentenipun antarane Serializable
lan Externalizable
dumunung ora mung ing "tambahan" akses kanggo programmer lan kemampuan kanggo luwih fleksibel ngatur proses, nanging uga ing proses dhewe. Kaping pisanan, ing mekanisme deserialization ... Nalika digunakake, Serializable
memori mung diparengake kanggo obyek, sawise kang nilai diwaca saka stream, kang isi kabeh kothak sawijining . Yen kita nggunakake Serializable
, konstruktor obyek ora disebut! Kabeh karya wis rampung liwat bayangan (Reflection API, kang kita sedhela kasebut ing pungkasan. kuliah). Ing kasus , Externalizable
mekanisme deseralisasi bakal beda. Ing wiwitan, konstruktor standar diarani. Lan mung banjur UserInfo
diarani metode obyek sing digawe readExternal()
, sing tanggung jawab kanggo ngisi kolom obyek kasebut. kok sembarang kelas sing ngleksanakake antarmuka Externalizable
kudu duwe konstruktor standar . Ayo ditambahake menyang kelas UserInfo
lan mbukak maneh 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 Ivan Ivanov UserInfo{firstName='Ivan', lastName='Ivanov', superSecretInformation='Data paspor Ivan Ivanov'} Prakara sing beda banget! Kaping pisanan, senar sing didekripsi kanthi data rahasia dikirim menyang konsol, banjur obyek kasebut pulih saka file ing format senar! Mangkene carane kita bisa ngrampungake kabeh masalah :) Topik serialisasi lan deseralisasi katon gampang, nanging kaya sing sampeyan ngerteni, ceramah kita dadi dawa. Lan ora mung iku! Ana luwih akeh subtleties nalika nggunakake saben antarmuka iki, nanging supaya saiki otak sampeyan ora njeblug saka volume informasi anyar, aku bakal sedhela dhaftar sawetara TCTerms penting lan nyedhiyani pranala menyang maca tambahan. Dadi apa maneh sampeyan kudu ngerti? Kaping pisanan , nalika nggawe serialisasi (ora Matter apa sampeyan nggunakake Serializable
utawa Externalizable
), mbayar manungsa waé kanggo variabel static
. Nalika digunakake, Serializable
kolom iki ora serialized ing kabeh (lan, miturut, Nilai ora ngganti, amarga static
kothak kagungane kelas, ora obyek). Nanging nalika nggunakake, Externalizable
sampeyan ngontrol proses kasebut dhewe, mula kanthi teknis iki bisa ditindakake. Nanging ora dianjurake, amarga iki kebak kesalahan subtle. Kapindho , manungsa waé uga kudu mbayar kanggo variabel karo modifiers final
. Nalika digunakake, Serializable
lagi serialized lan deserialized minangka biasanipun, nanging nalika digunakake, iku mokal Externalizable
kanggo deserialize final
variabel ! Alesané prasaja: kabeh final
-lapangan diinisialisasi nalika konstruktor standar diarani, lan sawise iku ora bisa diganti. Mulane, kanggo serialize obyek ngemot final
-fields, nggunakake serialization standar liwat Serializable
. Katelu , nalika nggunakake warisan, kabeh kelas warisan sing mudhun saka sawetara Externalizable
kelas uga kudu duwe konstruktor standar. Ing ngisor iki sawetara pranala menyang artikel sing apik babagan mekanisme serialisasi:
Sampai jumpa! :)
GO TO FULL VERSION