Вопрос-ответ

Why does Java have transient fields?

Почему в Java есть переходные поля?

Почему в Java есть переходные поля?

Переведено автоматически
Ответ 1

Ключевое слово transient в Java используется для указания того, что поле не должно быть частью процесса сериализации (что означает сохранение, например, в файл).

Из Спецификация языка Java, Java SE 7 Edition, Раздел 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 Developer Network) есть раздел, в котором обсуждается использование и представлен сценарий, в котором transient ключевое слово используется для предотвращения сериализации определенных полей.

Ответ 2

Прежде чем понимать ключевое слово 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, поэтому оно не будет сохранено в постоянном хранилище.

Ответ 3

Чтобы позволить вам определять переменные, которые вы не хотите сериализовать.

В объекте может содержаться информация, которую вы не хотите сериализовать / сохранять (возможно, ссылка на родительский объект factory), или, возможно, сериализовывать не имеет смысла. Пометка их как "временных" означает, что механизм сериализации будет игнорировать эти поля.

Ответ 4

Зачем в Java нужны временные поля?

Ключевое слово transient дает вам некоторый контроль над процессом сериализации и позволяет исключить некоторые свойства объекта из этого процесса. Процесс сериализации используется для сохранения объектов Java, в основном для того, чтобы их состояния могли сохраняться, пока они передаются или неактивны. Иногда имеет смысл не сериализовывать определенные атрибуты объекта.

Какие поля следует отметить как переходные?

Теперь, когда мы знаем назначение transient ключевого слова и переходных полей, важно знать, какие поля помечать как переходные. Статические поля также не сериализуются, поэтому соответствующее ключевое слово также сработает. Но это может испортить дизайн вашего класса; здесь на помощь приходит ключевое слово transient. Я стараюсь не допускать сериализации полей, значения которых могут быть получены из других, поэтому я помечаю их как временные. Если у вас есть поле с именем, interest значение которого может быть вычислено из других полей (principal, rate & time), нет необходимости сериализовывать его.

Еще один хороший пример - количество слов в статье. Если вы сохраняете статью целиком, на самом деле нет необходимости сохранять количество слов, потому что его можно вычислить, когда статья будет "десериализована". Или подумайте о регистраторах; Logger экземпляры почти никогда не нуждаются в сериализации, поэтому их можно сделать временными.

java