Почему у Java есть временные поля? - PullRequest
1345 голосов
/ 26 мая 2009

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

Ответы [ 13 ]

1565 голосов
/ 26 мая 2009

Ключевое слово 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 ключевое слово используется для предотвращения сериализации определенных полей.

399 голосов
/ 23 сентября 2012

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

Источник

82 голосов
/ 26 мая 2009

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

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

33 голосов
/ 19 марта 2014

Мой маленький вклад:

Что такое переходное поле?
По сути, любое поле, измененное с помощью ключевого слова transient, является временным.

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

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

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

23 голосов
/ 26 мая 2009

A transient переменная - это переменная, которая не может быть сериализована.

Один из примеров того, когда это может быть полезно, - это переменные, которые имеют смысл только в контексте конкретного экземпляра объекта и становятся недействительными после сериализации и десериализации объекта. В этом случае полезно, чтобы эти переменные стали null, чтобы вы могли при необходимости повторно инициализировать их полезными данными.

14 голосов
/ 26 марта 2010

transient используется для указания того, что поле класса не нуждается в сериализации. Вероятно, лучшим примером является поле Thread. Обычно нет смысла сериализовать Thread, так как его состояние очень «специфично для потока».

13 голосов
/ 28 мая 2009

Системы сериализации, кроме родной Java, также могут использовать этот модификатор. Например, Hibernate не будет сохранять поля, помеченные либо @ Transient , либо модификатором transient . Терракота также уважает этот модификатор.

Я полагаю, что переносное значение модификатора таково: «Это поле предназначено только для использования в памяти. Не сохраняйте и не перемещайте его вне этой конкретной ВМ. Оно непереносимо». то есть вы не можете полагаться на его значение в другой области памяти виртуальной машины. Подобно volatile означает, что вы не можете полагаться на определенную семантику памяти и потоков.

8 голосов
/ 26 мая 2009

Поскольку не все переменные имеют сериализуемую природу

6 голосов
/ 01 июля 2015

Прежде чем ответить на этот вопрос, я должен объяснить вам СЕРИАЛИЗАЦИЯ , потому что, если вы понимаете, что означает сериализация в научном компьютере, вы легко поймете это ключевое слово.

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

public class Foo implements Serializable 
{
 private String attr1;
 private String attr2;
 ...
}

Теперь, ЕСЛИ ВЫ ХОТИТЕ НЕ делать ПЕРЕДАЧА / СОХРАНЕННОЕ поле этого объекта SO , вы можете использовать ключевое слово transient

private transient attr2;

Пример

3 голосов
/ 26 мая 2009

Это необходимо, когда вы не хотите делиться конфиденциальными данными, которые используются при сериализации.

...