JavaRush /Blog Jawa /Random-JV /Antarmuka Externalizable ing Jawa

Antarmuka Externalizable ing Jawa

Diterbitake ing grup
Hello! Dina iki kita bakal nerusake introduksi kanggo serializing lan deserializing obyek Jawa. Ing kuliah pungkasan, kita dikenalake menyang antarmuka panandha Serializable , ndeleng conto panggunaane, lan uga sinau carane ngontrol proses serialisasi nggunakake tembung kunci transient . Inggih, "ngatur proses," mesthi, iku tembung kuwat. Kita duwe siji tembung kunci, siji ID versi, lan iku sejatine. Liyane saka proses "hardwired" nang Jawa, lan ora ana akses menyang. Saka titik penak tampilan, iki, mesthi, apik. Nanging programer ing karyane kudu fokus ora mung ing comfort dhewe, bener? :) Ana faktor liyane kanggo nimbang. Mulane, Serializable ora mung alat kanggo serialization-deserialisasi ing Jawa. Dina iki kita bakal kenal karo antarmuka Externalizable . Nanging sadurunge kita nerusake sinau, sampeyan bisa uga duwe pitakonan sing cukup: kenapa kita butuh alat liyane? SerializableAku 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 Serializablenduweni sawetara kekurangan. Ayo kita dhaptar sawetara:
  1. Kinerja. Antarmuka wis Serializableakeh kaluwihan, nanging kinerja dhuwur cetha ora siji saka wong-wong mau.

Ngenalke Antarmuka sing Bisa Dieksternalisasi - 2

Kaping pisanan , mekanisme internal Serializablengasilake 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 Serializableadhedhasar 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.

  1. 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 transientkanggo ngilangi sawetara data, lan kabeh iku. Kaya "toolkit" :/

  2. 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 Serializableora menehi kesempatan iki.

Ngenalke Antarmuka sing Bisa Dieksternalisasi - 3Inggih, ayo pungkasane ndeleng kaya apa kelas nggunakake 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, Externalizablesampeyan 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 outlan minangka paramèter ObjectInputsing 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 Ngenalke Antarmuka sing Bisa Dieksternalisasi - 4 Oops :( Pranyata ora dadi prasaja! Mekanisme deserialization mbuwang pangecualian lan mbutuhake kita nggawe konstruktor standar. Aku wonder apa? SerializableKita ngatur tanpa iku ... : / Kene kita teka menyang nuansa penting liyane Bentenipun antarane Serializablelan Externalizabledumunung 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, Serializablememori 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 , Externalizablemekanisme deseralisasi bakal beda. Ing wiwitan, konstruktor standar diarani. Lan mung banjur UserInfodiarani metode obyek sing digawe readExternal(), sing tanggung jawab kanggo ngisi kolom obyek kasebut. kok sembarang kelas sing ngleksanakake antarmuka Externalizablekudu duwe konstruktor standar . Ayo ditambahake menyang kelas UserInfolan 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 Serializableutawa Externalizable), mbayar manungsa waé kanggo variabel static. Nalika digunakake, Serializablekolom iki ora serialized ing kabeh (lan, miturut, Nilai ora ngganti, amarga statickothak kagungane kelas, ora obyek). Nanging nalika nggunakake, Externalizablesampeyan 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, Serializablelagi serialized lan deserialized minangka biasanipun, nanging nalika digunakake, iku mokal Externalizablekanggo deserialize finalvariabel ! 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 Externalizablekelas uga kudu duwe konstruktor standar. Ing ngisor iki sawetara pranala menyang artikel sing apik babagan mekanisme serialisasi: Sampai jumpa! :)
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION