Салом! Дар мақолаи имрӯза мо тағирдиҳандаи муваққатиро дар Java дида мебароем. Биёед дар бораи он ки чаро ин тағирдиҳанда лозим аст ва чӣ гуна онро дуруст истифода бурдан мумкин аст. Бирав!
атомҳо тақсим кунед . Биёед усулеро нависем шармандагии испанӣ Тағйирдиҳанда (ниҳоят)
Оё касе ошуфтааст, ки мо пароли корбарро захира кардем? Махсусан, чунин парол... Бале, бале, мо худамон офаридем, вале ба ҳар ҳол... Баъзан ҳолатҳое мешаванд, ки баъзе майдонҳоро сериализатсия кардан мумкин нест, ё беҳтараш ин корро накунед. Дар мисоли дар боло овардашуда, ман мехоҳам ҳамаи майдонҳоро ҷуз парол захира кунам. Чӣ тавр ба ин ноил шудан мумкин аст? Ҷавоб: тағирдиҳандаро истифода баред
Баъзе синфҳо баъзан майдонҳое доранд, ки дар асоси дигар соҳаҳо ё маълумоти дигар ҳисоб карда мешаванд. Онхо, гуем, дар парвоз хисоб карда мешаванд. Барои мисол овардани чунин соҳа, биёед фармоишро дар мағозаи онлайн ё ягон хидмати интиқоли ғизо тасаввур кунем. Ҳар як фармоиш, дар байни дигар маълумот, аз рӯйхати молҳо ва арзиши умумӣ иборат аст. Вай дар навбати худ аз арзиши умумии хар як махсулот иборат аст. Маълум мешавад, ки арзиши нихоиро «дастй» мукаррар кардан мумкин нест: он бояд ба таври программавй хисоб карда, арзиши хамаи молхоро чамъбаст кард. Майдонҳои ба ин монанд, ки бояд ба таври барномавӣ ҳисоб карда шаванд, ба силсиласозӣ ниёз надоранд. Аз ин рӯ, мо онҳоро бо тағирдиҳанда қайд мекунем
Инчунин баъзе синфҳо мавҷуданд, ки маълумоти шахсиро нигоҳ медоранд. Мо дар аввали мақола як мисоли чунин синфро дида баромадем. Шумо набояд иҷозат надиҳед, ки чунин маълумот берун аз JVM паҳн шавад. Аз ин рӯ, майдонҳое, ки чунин маълумот доранд, бояд бо тағирдиҳанда қайд карда шаванд,
Баъзан синф дорои майдонҳо - an objectҳои синфҳои дигар аст, ки интерфейсро амалӣ намекунанд
Хуб, як чизи охирин. Барои силсила кардани майдонҳое, ки ҷузъи иттилооти ҳолати an object нестанд, лозим нест. Намунаҳои дар боло овардашуда ба ин қоида дохил мешаванд. Аммо шумо инчунин метавонед дар ин ҷо ҳамаи майдонҳои дигареро, ки барои ислоҳ кардан ё иҷрои ягон вазифаи хидматӣ илова карда шудаанд, дохил кунед, ки дар бораи ҳолати an object маълумот надоранд.
Биёед сериализатсияро ба ёд орем
Тағйирдиҳандаtransient
дар раванди силсиласозӣ ва ғайрисериализатсияи an objectҳо истифода мешавад. Пас биёед аввал дар ин бора мухтасар сухан ронем. Фарз мекунем, ки мо ягон an object дорем ва он дорои майдонҳое мебошад, ки ҳар кадоми онҳо арзиш доранд. Хамаи ин холати an object номида мешавад. Сериализатсия табдил додани ҳолати an object ба пайдарпайии byteҳо мебошад. Ин byteҳо одатан дар ягон файл нигоҳ дошта мешаванд. Десериализатсия раванди баръакс аст. Биёед тасаввур кунем, ки мо an objectро ба byteҳо силсилавӣ кардем ва ин маҷмӯи byteҳоро дар ягон файл нигоҳ доштем. Ҳангоми бекор кардани серия, барнома ба инҳо ниёз дорад:
- Маҷмӯи byteҳоро аз файл хонед.
- Аз ин маҷмӯи byteҳо an objectи ибтидоӣ созед ва ҳар як майдонро ба арзише, ки an object дар вақти сериализатсия дошт, таъин кунед.
Биёед дар амал сериализатсияро ба ёд орем
Хуб, ҳоло биёед ба сериализатсия дар амал назар кунем. Агар шумо хоҳед, ки мавзӯъро хубтар дарк кунед, мо тавсия медиҳем, ки маводро дар Java хонед Serialization ва deserialization . Хуб, дар ин мақола мо аз боло рафта, рост ба мисолҳо меравем. Фарз мекунем, ки мо синфе доремUser
, ки дорои як қатор майдонҳо, қабулкунандаҳо ва танзимкунандагон ва як метод аст toString
:
public class User implements Serializable {
private static final long serialVersionUID = 1L;
private String firstName;
private String lastName;
private String email;
private LocalDate birthDate;
private String login;
private String password;
public User() {}
public User(String firstName, String lastName, String email, LocalDate birthDate, String login, String password) {
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
this.birthDate = birthDate;
this.login = login;
this.password = password;
}
/*
Геттеры, Сеттеры
*/
@Override
public String toString() {
return "User{" +
"firstName='" + firstName + '\'' +
", lastName='" + lastName + '\'' +
", email='" + email + '\'' +
", birthDate=" + birthDate +
", login='" + login + '\'' +
", password='" + password + '\'' +
'}';
}
}
Мо мехоҳем дар оянда an objectҳои ин синфро силсилавӣ кунем. Биёед усулеро нависем, ки an object User
ва сатрро мегирад path
- роҳ ба файле, ки дар он byteҳоро захира мекунем:
static void serialize(User user, String path) throws IOException {
FileOutputStream outputStream = null;
ObjectOutputStream objectOutputStream = null;
try {
//create 2 threads to serialize the object and save it to a file
outputStream = new FileOutputStream(path);
objectOutputStream = new ObjectOutputStream(outputStream);
// сохраняем an object в файл
objectOutputStream.writeObject(user);
} finally {
// Закроем потоки в блоке finally
if (objectOutputStream != null) {
objectOutputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
}
}
Мо инчунин усули бесериализатсияро менависем. Усул сатрро мегирад path
(роҳ ба файле, ки аз он an object "бор карда мешавад") ва an objectи навъи : -ро бармегардонад User
:
static User deserialize(String path) throws IOException, ClassNotFoundException {
FileInputStream fileInputStream = null;
ObjectInputStream objectInputStream = null;
try {
//создаем 2 потока для десериализации an object из file
fileInputStream = new FileInputStream(path);
objectInputStream = new ObjectInputStream(fileInputStream);
//загружаем an object из file
return (User) objectInputStream.readObject();
} finally {
if (fileInputStream != null) {
fileInputStream.close();
}
if (objectInputStream != null) {
objectInputStream.close();
}
}
}
Ҳама асбобҳо барои истифода омодаанд. Вақти он расидааст, ки byteҳоро ба main
, ки дар он мо an objectи синфро эҷод мекунем User
ва онро силсилавӣ мекунем. Пас мо онро бор мекунем ва бо он чизе, ки дар аввал буд, муқоиса мекунем:
public static void main(String[] args) throws IOException, ClassNotFoundException {
// вставьте свой путь до file
final String path = "/home/zor/user.ser";
// create our object
User user = new User();
user.setFirstName("Stefan");
user.setLastName("Smith");
user.setEmail("ssmith@email.com");
user.setBirthDate(LocalDate.of(1991, 7, 16));
user.setLogin("ssmith");
user.setPassword("gemma_arterton_4ever_in_my_heart91");
System.out.println("Initial user: " + user + "\r\n");
serialize(user, path);
User loadedUser = deserialize(path);
System.out.println("Loaded user from file: " + loadedUser + "\r\n");
}
Агар мо усулро иҷро кунем, мо натиҷаи зеринро мебинем:
Initial user: User{firstName='Stefan', lastName='Smith', email='ssmith@email.com', birthDate=1991-07-16, login='ssmith', password='gemma_arterton_4ever_in_my_heart91'}
Loaded user from file: User{firstName='Stefan', lastName='Smith', email='ssmith@email.com', birthDate=1991-07-16, login='ssmith', password='gemma_arterton_4ever_in_my_heart91'}
Тавре ки шумо аз баромад мебинед, an objectҳо якхелаанд. Аммо як чизи хурд вуҷуд дорад, аммо ... Ва маҳз дар ин ҷо transient
ба бозӣ меояд .
Тағйирдиҳанда (ниҳоят)transient
Оё касе ошуфтааст, ки мо пароли корбарро захира кардем? Махсусан, чунин парол... Бале, бале, мо худамон офаридем, вале ба ҳар ҳол... Баъзан ҳолатҳое мешаванд, ки баъзе майдонҳоро сериализатсия кардан мумкин нест, ё беҳтараш ин корро накунед. Дар мисоли дар боло овардашуда, ман мехоҳам ҳамаи майдонҳоро ҷуз парол захира кунам. Чӣ тавр ба ин ноил шудан мумкин аст? Ҷавоб: тағирдиҳандаро истифода баред transient
. transient
тағирдиҳандаест, ки дар назди майдони синф ҷойгир карда шудааст (монанди дигар тағирдиҳандаҳо ба монанди public
, final
ва ғ.) барои нишон додани он, ки майдон набояд силсилаи карда шавад. Майдонҳое, ки бо калимаи калидӣ қайд карда шудаанд, transient
серия карда намешаванд. Акнун биёед мисолро бо корбари худ таҳрир кунем, то нофаҳмиҳои хурдро ислоҳ кунем ва пароли корбарро захира накунем. Барои ин, майдони мувофиқро дар синф бо калимаи калидӣ қайд кунед transient
:
public class User implements Serializable {
private static final long serialVersionUID = 1L;
private String firstName;
private String lastName;
private String email;
private LocalDate birthDate;
private String login;
private transient String password;
/*
Конструкторы, геттеры, сеттеры, toString...
*/
}
Агар мо усулро аз мисоли боло бори дигар иҷро кунем main
, мо мебинем, ки парол захира нашудааст:
Initial user: User{firstName='Stefan', lastName='Smith', email='ssmith@email.com', birthDate=1991-07-16, login='ssmith', password='gemma_arterton_4ever_in_my_heart91'}
Loaded user from file: User{firstName='Stefan', lastName='Smith', email='ssmith@email.com', birthDate=1991-07-16, login='ssmith', password='null'}
Аҷоиб, мо ба ҳадафи худ расидем ва маълумоти махфиро нигоҳ намедорем. Махсусан ин гуна маълумот... (бахшед)
Кай барои истифодаи муваққатӣ?
Барои ворид шудан ба контексти сериализатсия намуна бо корбар лозим буд. Акнун биёед муфассалтар дар бораи кай истифода бурдани тағирдиҳанда сӯҳбат кунемtransient
.
- Майдонҳое, ки ба таври барномавӣ ҳисоб карда мешаванд
Баъзе синфҳо баъзан майдонҳое доранд, ки дар асоси дигар соҳаҳо ё маълумоти дигар ҳисоб карда мешаванд. Онхо, гуем, дар парвоз хисоб карда мешаванд. Барои мисол овардани чунин соҳа, биёед фармоишро дар мағозаи онлайн ё ягон хидмати интиқоли ғизо тасаввур кунем. Ҳар як фармоиш, дар байни дигар маълумот, аз рӯйхати молҳо ва арзиши умумӣ иборат аст. Вай дар навбати худ аз арзиши умумии хар як махсулот иборат аст. Маълум мешавад, ки арзиши нихоиро «дастй» мукаррар кардан мумкин нест: он бояд ба таври программавй хисоб карда, арзиши хамаи молхоро чамъбаст кард. Майдонҳои ба ин монанд, ки бояд ба таври барномавӣ ҳисоб карда шаванд, ба силсиласозӣ ниёз надоранд. Аз ин рӯ, мо онҳоро бо тағирдиҳанда қайд мекунем transient
.
class Order implements Serializable {
private List- items;
private transient BigDecimal totalAmount; //вычисляется на ходу
}
- Майдонҳо бо маълумоти хусусӣ
Инчунин баъзе синфҳо мавҷуданд, ки маълумоти шахсиро нигоҳ медоранд. Мо дар аввали мақола як мисоли чунин синфро дида баромадем. Шумо набояд иҷозат надиҳед, ки чунин маълумот берун аз JVM паҳн шавад. Аз ин рӯ, майдонҳое, ки чунин маълумот доранд, бояд бо тағирдиҳанда қайд карда шаванд, transient
агар шумо чунин синфро сериализатсия кунед.
- Майдонҳое, ки интерфейсро амалӣ намекунанд
Serializable
Баъзан синф дорои майдонҳо - an objectҳои синфҳои дигар аст, ки интерфейсро амалӣ намекунанд Serializable
Serializable
. Намунаҳои чунин майдонҳо логгерҳо, ҷараёнҳои воридот/х, an objectҳое мебошанд, ки пайвастҳои пойгоҳи додаҳо ва дигар синфҳои утorтаҳоро нигоҳ медоранд. Агар шумо кӯшиш кунед, ки an objectеро, ки дорои майдонҳои сериализатсиянашаванда аст, сериализатсия кунед, шумо хатогӣ мегиред java.io.NotSerializableException
. Барои пешгирӣ кардани ин, ҳама майдонҳое, ки интерфейсро иҷро намекунанд, Serializable
бояд бо тағирдиҳанда қайд карда шаванд transient
.
public class FileReader implements Serializable {
// Первые 2 поля не реализуют Serializable
// Помечаем их How transient поля
private transient InputStream is;
private transient BufferedReader buf;
private String fileName;
// Constructors, Getters, Setters
public String readFile() throws IOException {
try {
is = new FileInputStream(fileName);
buf = new BufferedReader(new InputStreamReader(is));
String line = buf.readLine();
StringBuilder sb = new StringBuilder();
while (line != null) {
sb.append(line).append("\n");
line = buf.readLine();
}
return sb.toString();
} finally {
if (buf != null) {
buf.close();
}
if (is != null) {
is.close();
}
}
}
}
- Майдонҳо бо маълумот дар бораи ҳолати an object
Хуб, як чизи охирин. Барои силсила кардани майдонҳое, ки ҷузъи иттилооти ҳолати an object нестанд, лозим нест. Намунаҳои дар боло овардашуда ба ин қоида дохил мешаванд. Аммо шумо инчунин метавонед дар ин ҷо ҳамаи майдонҳои дигареро, ки барои ислоҳ кардан ё иҷрои ягон вазифаи хидматӣ илова карда шудаанд, дохил кунед, ки дар бораи ҳолати an object маълумот надоранд.
transient
Ваfinal
Натиҷаҳо
Ҳамааш ҳамин. Имрӯз мо дар бораи тағирдиҳанда сӯҳбат кардемtransient
:
- Мо сериализатсияро дар назария ва амалия ба хотир овардем.
- Мо фаҳмидем, ки барои сериализатсия накардани баъзе майдонҳои синф, онҳо бояд бо тағирдиҳанда қайд карда шаванд
transient
. - Мо муҳокима кардем, ки дар кадом ҳолатҳо ин тағирдиҳанда бояд истифода шавад. Чор чунин ҳолат вуҷуд дошт:
- майдонҳое, ки ба таври барномавӣ ҳисоб карда мешаванд;
- майдонҳое, ки маълумоти махфӣ доранд;
- майдонҳое, ки интерфейсро татбиқ намекунанд
Serializable
; - майдонҳое, ки қисми ҳолати an object нестанд.
GO TO FULL VERSION