Відповіді:
transient
Ключове слово в Java використовується для вказівки того, що поле не повинно бути частиною сериализации (що означає порятунок, як в файл) процес.
З специфікації мови Java, видання Java SE 7 , розділ 8.3.1.3. transient
Поля :
Змінні можуть бути позначені,
transient
щоб вказати, що вони не є частиною стійкого стану об'єкта.
Наприклад, у вас можуть бути поля, отримані з інших полів, і їх слід робити лише програмно, а не для того, щоб стан зберігався за допомогою серіалізації.
Ось GalleryImage
клас, який містить зображення та мініатюру, отриману із зображення:
class GalleryImage implements Serializable
{
private Image image;
private transient Image thumbnailImage;
private void generateThumbnail()
{
// Generate thumbnail.
}
private void readObject(ObjectInputStream inputStream)
throws IOException, ClassNotFoundException
{
inputStream.defaultReadObject();
generateThumbnail();
}
}
У цьому прикладі thumbnailImage
є мініатюрне зображення, яке генерується за допомогою виклику generateThumbnail
методу.
thumbnailImage
Поле позначаються як transient
, тому тільки оригінальна image
сериализация , а не зберігаються як вихідне зображення і зменшене зображення. Це означає, що для збереження серіалізованого об’єкта знадобиться менше місця для зберігання. (Звичайно, це може бути або не бажано залежно від вимог системи - це лише приклад.)
Під час десеріалізації readObject
метод викликається для виконання будь-яких операцій, необхідних для відновлення стану об'єкта до стану, в якому відбулася серіалізація. Тут потрібно створити мініатюру, тож readObject
метод буде відмінено, щоб мініатюра була сформована шляхом виклику generateThumbnail
методу.
Для отримання додаткової інформації, у статті " Розкрийте секрети програми Java Serialization API" (яка спочатку була доступна в Мережі розробників Sun) є розділ, в якому обговорюється використання та представлений сценарій, коли transient
ключове слово використовується для запобігання серіалізації певних полів.
Перш ніж зрозуміти transient
ключове слово, треба зрозуміти поняття серіалізації. Якщо читач знає про серіалізацію, пропустіть перший пункт.
Серіалізація - це процес збереження стану об'єкта. Це означає, що стан об'єкта перетворюється в потік байтів, який буде використовуватися для збереження (наприклад, зберігання байтів у файлі) або передачі (наприклад, відправлення байтів через мережу). Таким же чином ми можемо використовувати десяріалізацію для повернення стану об'єкта з байтів. Це одна з важливих концепцій програмування Java, оскільки серіалізація здебільшого використовується в мережевому програмуванні. Об'єкти, які потрібно передати через мережу, повинні бути перетворені в байти. Для цього кожен клас або інтерфейс повинен реалізувати Serializable
інтерфейс. Це маркерний інтерфейс без будь-яких методів.
transient
ключове слово та його мета?За замовчуванням всі змінні об'єкта перетворюються в стійкий стан. У деяких випадках ви можете уникати збереження деяких змінних, оскільки у вас немає необхідності зберігати ці змінні. Таким чином, ви можете оголосити ці змінні як transient
. Якщо змінна оголошена як transient
, вона не збережеться. Це головна мета transient
ключового слова.
Я хочу пояснити вищезазначені два моменти наступним прикладом:
package javabeat.samples;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
class NameStore implements Serializable{
private String firstName;
private transient String middleName;
private String lastName;
public NameStore (String fName, String mName, String lName){
this.firstName = fName;
this.middleName = mName;
this.lastName = lName;
}
public String toString(){
StringBuffer sb = new StringBuffer(40);
sb.append("First Name : ");
sb.append(this.firstName);
sb.append("Middle Name : ");
sb.append(this.middleName);
sb.append("Last Name : ");
sb.append(this.lastName);
return sb.toString();
}
}
public class TransientExample{
public static void main(String args[]) throws Exception {
NameStore nameStore = new NameStore("Steve", "Middle","Jobs");
ObjectOutputStream o = new ObjectOutputStream(new FileOutputStream("nameStore"));
// writing to object
o.writeObject(nameStore);
o.close();
// reading from object
ObjectInputStream in = new ObjectInputStream(new FileInputStream("nameStore"));
NameStore nameStore1 = (NameStore)in.readObject();
System.out.println(nameStore1);
}
}
А вихід буде наступним:
First Name : Steve
Middle Name : null
Last Name : Jobs
Прізвище оголошено як transient
, тому воно не зберігатиметься в постійному сховищі.
NameFormatter
використаний для керування автомобілем toString()
. Або все, що стосується конфігурації, перегляду чи ділової логіки ... на відміну від даних.
Щоб ви могли визначити змінні, які ви не хочете серіалізувати.
В об’єкті у вас може бути інформація, яку ви не хочете серіалізувати / зберігати (можливо, посилання на батьківський заводський об'єкт), або, можливо, не має сенсу серіалізувати. Позначення їх як "перехідних" означає, що механізм серіалізації ігнорує ці поля.
Мій невеликий внесок:
Що таке перехідне поле?
По суті, будь-яке поле, модифіковане transient
ключовим словом, є тимчасовим полем.
Чому потрібні перехідні поля на Java? Ключове слово дає деякий контроль над процесом сериализации і дозволяє виключити деякі властивості об'єктів з цього процесу. Процес серіалізації використовується для збереження об'єктів Java, здебільшого для того, щоб їхні стани зберігалися під час їх перенесення чи неактивності. Іноді має сенс не серіалізувати певні атрибути об’єкта. Які поля слід позначити перехідними?
Тепер ми знаємо метуtransient
transient
ключові слова та перехідні поля, важливо знати, які поля позначати перехідними. Статичні поля також не серіалізуються, тому відповідне ключове слово також зробить трюк. Але це може зіпсувати дизайн вашого класу; саме тут transient
на допомогу приходить ключове слово. Я намагаюся не допускати серіалізації полів, значення яких можуть бути отримані від інших, тому я позначаю їх перехідними. Якщо у вас є поле під назвою interest
, значення якого можна обчислити з інших полів ( principal
, rate
& time
), не потрібно його серіалізувати.
Ще один хороший приклад - кількість підрахунків у статті. Якщо ви зберігаєте всю статтю, насправді не потрібно зберігати кількість слів, оскільки її можна обчислити, коли стаття стає "дезаріалізованою". Або подумайте про лісоруби;Logger
екземпляри майже ніколи не потребують серіалізації, тому вони можуть бути перехідними.
transient
transient
transient
Змінна є змінною , яка не може бути серіалізациі.
Один з прикладів, коли це може бути корисним, - це змінні, які мають сенс лише в контексті конкретного об'єкта, які стають недійсними після того, як ви серіалізуєте та десеріалізуєте об'єкт. У цьому випадку корисно, щоб ці змінні стали null
замість них, щоб ви могли повторно ініціалізувати їх з корисними даними, коли це необхідно.
transient
використовується для вказівки, що поле класу не потрібно серіалізувати. Напевно, найкращий приклад - Thread
поле. Зазвичай не існує причин для серіалізації Thread
, оскільки його стан дуже «специфічний для потоку».
A
посилається на не серіалізаційний клас B
(як Thread
у вашому прикладі), то A
повинен або позначити посилання, оскільки transient
XOR повинен переосмислити процес серіалізації за замовчуванням, щоб зробити щось розумне з B
XOR, припустимо, що B
насправді посилаються лише серіалізаційні підкласи (тому власне підклас повинен піклуватися про свого «поганого» батька B
) XOR приймає, що серіалізація не вдасться. Лише в одному випадку (позначеному як перехідний) B
автоматично і безшумно пропускається.
Системи серіалізації, крім рідної Java, також можуть використовувати цей модифікатор. Наприклад, сплячий режим не буде зберігати поля, позначені або символом @Transient, або модифікатором перехідного періоду . Теракота також поважає цей модифікатор.
Я вважаю, що переносне значення модифікатора полягає в тому, що "це поле призначене лише для використання в пам'яті. Не зберігайте і не переміщуйте його за межами цієї конкретної ВМ. Нічим не переносяться". тобто ви не можете розраховувати на його значення в іншому просторі пам'яті VM. Так само, як летючі засоби, ви не можете розраховувати на певну семантику пам'яті та потоків.
transient
це не було б ключовим словом, якби воно було розроблено в цей час. Вони, ймовірно, будуть використовувати примітку.
Тому що не всі змінні мають серійний характер
Перш ніж відповісти на це запитання, я мушу пояснити вам СЕРІАЛІЗАЦІЮ , адже якщо ви зрозумієте, що це означає серіалізація в науковому комп’ютері, ви можете легко зрозуміти це ключове слово.
Серіалізація
Коли об'єкт передається через мережу / зберігається на фізичному носії (файл, ...), об'єкт повинен бути "серіалізований". Серіалізація перетворює ряд об'єктів статусу байт. Ці байти надсилаються в мережу / зберігаються, і об'єкт заново створюється з цих байтів.
Приклад
public class Foo implements Serializable
{
private String attr1;
private String attr2;
...
}
Тепер , якщо ви хочете зробити НЕ TRANSFERT / збереження поле цього об'єкта SO , ви можете використовувати ключове слово transient
private transient attr2;
Це потрібно, коли ви не хочете ділитися чутливими даними, які йдуть із серіалізацією.
Thread
(наприклад, кредит на @AH), і в такому випадку ви позначите його як перехідне. Однак нитка сама по собі не є чутливими даними, вона просто не має ніякого логічного сенсу її серіалізувати (і це не можна серіалізувати).
Згідно з перехідним значенням google == триває лише короткий час; непостійний.
Тепер, якщо ви хочете зробити що-небудь тимчасове в Java, використовуйте ключове слово перехідне.
Q: де використовувати перехідне?
Відповідь: Як правило, у Java ми можемо зберігати дані у файли, отримуючи їх у змінних і записуючи ці змінні у файли, цей процес відомий як серіалізація. Тепер, якщо ми хочемо уникнути запису змінних даних у файл, ми зробимо цю змінну перехідною.
transient int result=10;
Примітка: перехідні змінні не можуть бути локальними.
Простіше кажучи, перехідне ключове слово java захищає поля від Serialize як їх непрохідні поля, що зустрічаються.
У цьому фрагменті коду наш абстрактний клас BaseJob реалізує інтерфейс Serializable, ми поширюємося з BaseJob, але нам не потрібно серіалізувати віддалені та локальні джерела даних; серіалізувати лише поля організаціїName та isSynced.
public abstract class BaseJob implements Serializable{
public void ShouldRetryRun(){}
}
public class SyncOrganizationJob extends BaseJob {
public String organizationName;
public Boolean isSynced
@Inject transient RemoteDataSource remoteDataSource;
@Inject transient LocalDaoSource localDataSource;
public SyncOrganizationJob(String organizationName) {
super(new
Params(BACKGROUND).groupBy(GROUP).requireNetwork().persist());
this.organizationName = organizationName;
this.isSynced=isSynced;
}
}
Спрощений приклад коду для перехідних ключових слів.
import java.io.*;
class NameStore implements Serializable {
private String firstName, lastName;
private transient String fullName;
public NameStore (String fName, String lName){
this.firstName = fName;
this.lastName = lName;
buildFullName();
}
private void buildFullName() {
// assume building fullName is compuational/memory intensive!
this.fullName = this.firstName + " " + this.lastName;
}
public String toString(){
return "First Name : " + this.firstName
+ "\nLast Name : " + this.lastName
+ "\nFull Name : " + this.fullName;
}
private void readObject(ObjectInputStream inputStream)
throws IOException, ClassNotFoundException
{
inputStream.defaultReadObject();
buildFullName();
}
}
public class TransientExample{
public static void main(String args[]) throws Exception {
ObjectOutputStream o = new ObjectOutputStream(new FileOutputStream("ns"));
o.writeObject(new NameStore("Steve", "Jobs"));
o.close();
ObjectInputStream in = new ObjectInputStream(new FileInputStream("ns"));
NameStore ns = (NameStore)in.readObject();
System.out.println(ns);
}
}
Поле, яке оголошується перехідним модифікатором, не братиме участі в серіалізованому процесі. Коли об'єкт серіалізується (зберігається в будь-якому стані), значення його перехідних полів ігноруються в послідовному поданні, тоді як поля, відмінні від перехідних полів, будуть брати участь у процесі серіалізації. Саме це і є основною метою перехідного ключового слова.
@DoNotSerialize
?