Serializable
Ман аз ухдаи кори худ баромадам ва ба таври автоматй ба амал баровардани тамоми процесс хурсанд нашуда наметаво-над. Мисолҳое, ки мо дида будем, низ мураккаб набуданд. Пас, чӣ кор аст? Чаро интерфейси дигар барои аслан як вазифа? Гап дар сари он аст, ки Serializable
вай як катор камбудихо дорад. Биёед баъзе аз онҳоро номбар кунем:
-
Намоиш. Интерфейс
Serializable
бартариҳои зиёд дорад, аммо иҷрои баланд ба таври возеҳ яке аз онҳо нест.
Аввалан , механизми дохилӣ Serializable
ҳангоми кор миқдори зиёди иттилооти хидматӣ ва намудҳои гуногуни маълумоти муваққатиро тавлид мекунад.
Сониян (ба шумо лозим нест, ки ҳоло ба ин ворид шавед ва агар шумо таваҷҷӯҳ дошта бошед, дар вақти холӣ хонед), кор Serializable
ба истифодаи Reflection API асос ёфтааст. Ин зиддият ба шумо имкон медиҳад корҳое кунед, ки дар Java ғайриимкон ба назар мерасанд: масалан, арзишҳои майдонҳои хусусиро тағир диҳед. JavaRush дорои мақолаи олиҷаноб дар бораи Reflection API мебошад , шумо метавонед дар ин ҷо хонед.
-
чандирӣ. Мо ҳангоми истифодаи
Serializable
.Аз як тараф, ин хеле қулай аст, зеро агар мо воқеан ба кор аҳамият надиҳем, қобorяти навиштани code қулай ба назар мерасад. Аммо чӣ мешавад, агар ба мо дар ҳақиқат лозим аст, ки баъзе хусусиятҳои шахсии худро илова кунем (намунаи яке аз онҳо дар зер оварда мешавад) ба мантиқи сериализатсия?
Аслан, ҳама чизеро, ки мо бояд равандро назорат кунем, калимаи калидӣ
transient
барои истисно кардани баъзе маълумотҳост ва ҳамин тавр. Як навъ ба "маҷмӯаи асбобҳо": / -
Бехатарӣ. Ин нукта қисман аз нуқтаи қаблӣ бармеояд.
Мо қаблан дар ин бора чандон фикр накарда будем, аммо чӣ мешавад, агар баъзе маълумот дар синфи шумо барои "гӯши одамони дигар" (аниқтараш, чашмҳо) пешбинӣ нашуда бошад? Мисоли оддӣ парол ё дигар маълумоти шахсии корбар аст, ки дар ҷаҳони муосир бо як қатор қонунҳо танзим карда мешаванд.
Бо истифода аз он
Serializable
, мо воқеан дар ин бора коре карда наметавонем. Мо ҳама чизро тавре, ки ҳаст, сериал мекунем.Аммо, ба таври хуб, мо бояд ин гуна маълумотро пеш аз навиштан ба файл ё интиқоли он тавассути шабака рамзгузорӣ кунем. Аммо
Serializable
ин имкониятро намедихад.
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 {
}
}
Тавре ки шумо мебинед, мо дигаргуниҳои назаррас ба амал овардем! Як чизи асосӣ аён аст: ҳангоми татбиқи интерфейс, Externalizable
шумо бояд ду усули ҳатмиро татбиқ кунед - writeExternal()
ва readExternal()
. Тавре ки мо қаблан гуфта будем, тамоми масъулияти сериализатсия ва бесериализатсия ба дӯши барномасоз аст. Аммо, акнун шумо метавонед масъалаи набудани назоратро аз болои ин раванд ҳал кунед! Тамоми раванд мустақиман аз ҷониби шумо барномарезӣ карда мешавад, ки ин, албатта, механизми хеле чандиртарро эҷод мекунад. Илова бар ин, мушкилоти амният низ ҳал карда мешавад. Тавре ки шумо мебинед, мо дар синфи худ як майдон дорем: маълумоти шахсиро, ки бидуни рамз нигоҳ доштан мумкин нест. Акнун мо метавонем ба осонӣ codeеро нависем, ки ба ин маҳдудият ҷавобгӯ бошад. Масалан, ба синфи мо ду усули оддии хусусиро барои рамзгузорӣ ва рамзкушоии маълумоти махфӣ илова кунед. Мо онҳоро ба файл менависем ва онҳоро аз файл дар шакли рамзгузорӣ мехонем. Ва мо маълумоти боқимондаро тавре менависем ва мехонем :) Дар натиҷа, синфи мо чунин хоҳад буд:
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;
}
}
Мо ду усулро татбиқ кардем, ки ҳамон ObjectOutput out
ва ҳамчун параметрҳоеро истифода мебаранд ObjectInput
, ки мо аллакай дар лексия дар бораи Serializable
. Дар вақти лозима, мо маълумоти заруриро рамзгузорӣ ё рамзкушоӣ мекунем ва дар ин шакл мо онро барои силсилаи an objectи худ истифода мебарем. Биёед бубинем, ки ин дар амал чӣ гуна хоҳад буд:
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();
}
}
Дар encryptString()
ва усулҳо decryptString()
, мо махсусан баромадро ба консол илова кардем, то санҷед, ки маълумоти махфӣ дар кадом шакл навишта ва хонда мешавад. Рамзи дар боло овардашуда сатри зеринро ба консол мебарорад: SXZhbiBJdmFub3YncyBwYXNzcG9ydCBkYXRh Рамзгузорӣ муваффақ шуд! Мундариҷаи пурраи файл чунин аст: ¬н sr UserInfoГ!}ҐџC‚ћ xpt Ivant Ivanovt $SXZhbiBJdmFub3YncyBwYXNzcG9ydCBkYXRhx Акнун биёед кӯшиш кунем, ки мантиқи бесериализатсияи навиштаамонро истифода барем.
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();
}
}
Хуб, дар ин ҷо ҳеҷ чизи мураккабе ба назар намерасад, он бояд кор кунад! Биёед иҷро кунем... Истисно дар риштаи "main" java.io.InvalidClassException: UserInfo; ҳеҷ конструктори дуруст нест Оҳ :( Маълум шуд, ки он қадар оддӣ набуд! Механизми бесериализатсия истисноро ба вуҷуд овард ва аз мо талаб кард, ки конструктори пешфарз созем. Ман ҳайронам, ки чаро? Serializable
Мо бе он муваффақ шудем... :/ Инак, мо ба як нозукии муҳими дигар меоем. Фарқи байни Serializable
ва Externalizable
на танҳо дар дастрасии "васеъ" барои барномасоз ва қобorяти чандиртар идора кардани раванд, балки дар худи раванд аст.. Пеш аз ҳама, дар механизми бесериализатсия ... Ҳангоми истифода, Serializable
хотира оддӣ аст. барои an object ҷудо карда мешавад, ки пас аз он арзишҳо аз ҷараён хонда мешаванд, ки ҳамаи майдонҳои онро пур мекунанд Serializable
. лексия).Дар сурати , Externalizable
механизми бесериясозӣ гуногун хоҳад буд.Дар аввал конструктори пешфарз даъват карда мешавад.Ва танҳо баъд UserInfo
ба усули an objectи сохташуда даъват карда мешавад readExternal()
, ки барои пур кардани майдонҳои an object масъул аст. чаро ҳама синфе, ки интерфейсро амалӣ мекунад, Externalizable
бояд конструктори пешфарз дошта бошад . Биёед онро ба синфи худ илова кунем UserInfo
ва codeро дубора иҷро кунем:
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();
}
}
Баромади консол: Маълумоти шиносномаи Ivan Ivanов UserInfo{firstName='Ivan', lastName='Ivanov', superSecretInformation='Маълумоти шиносномаи Ivan Ivanов'} Масъалаи тамоман дигар! Аввалан, сатри рамзкушошуда бо маълумоти махфӣ ба консол бароварда шуд ва сипас an objectи мо аз файл дар формати сатр барқарор карда шуд! Хамин тавр мо хамаи проблемахоро бомуваффакият хал кардем :) Мавзуи сериализация ва бесериализация ба назар содда аст, аммо чи тавре ки мебинед, лекцияхои мо дароз шуданд. Ва ин ҳама нест! Ҳангоми истифодаи ҳар яке аз ин интерфейсҳо боз бисёр нозукиҳо вуҷуд доранд, аммо барои он ки ҳоло майнаи шумо аз ҳаҷми иттилооти нав таркида нашавад, ман ба таври мухтасар чанд нуктаи муҳими дигарро номбар мекунам ва истинодҳоро ба хониши иловагӣ пешкаш мекунам. Пас боз чиро донистан лозим аст? Аввалан , ҳангоми сериализатсия (фарқ надорад, ки шумо истифода мебаред Serializable
ё Externalizable
), ба тағирёбандаҳо диққат диҳед static
. Ҳангоми истифода, Serializable
ин майдонҳо умуман серия карда намешаванд (ва мутаносибан арзиши онҳо тағир намеёбад, зеро static
майдонҳо ба синф тааллуқ доранд, на ба an object). Аммо ҳангоми истифода бурдани он, Externalizable
шумо раванди худро худатон назорат мекунед, бинобар ин аз ҷиҳати техникӣ ин корро кардан мумкин аст. Аммо ин тавсия дода намешавад, зеро ин бо хатогиҳои нозук печида аст. Сониян , инчунин бояд ба тағирёбандаҳо бо тағирёбанда диққат дод final
. Вақте ки истифода мешаванд, Serializable
онҳо ҳамчун муқаррарӣ силсилавӣ ва ғайрисериявӣ карда мешаванд, аммо ҳангоми истифода, тағирёбандаро Externalizable
бесерия карданfinal
ғайриимкон аст ! Сабаб оддӣ аст: ҳамаи final
-майдонҳо ҳангоми даъват кардани конструктори пешфарз оғоз карда мешаванд ва баъд аз ин арзиши онҳо тағир дода намешавад. Аз ин рӯ, барои силсиласозии an objectҳои дорои final
-майдонҳо, силсиласозии стандартиро тавассути Serializable
. Сеюм , ҳангоми истифодаи мерос, ҳама синфҳои меросхӯре, ки аз баъзе Externalizable
синфҳо меоянд, бояд конструкторҳои пешфарз дошта бошанд. Инҳоянд чанд истинод ба мақолаҳои хуб дар бораи механизмҳои сериализатсия:
То дидор! :)
GO TO FULL VERSION