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


Почему Java имеет транзиторная полей?

13 1224

13 ответов:

The transient ключевое слово в Java используется, чтобы указать, что поле не должно быть сериализовано.

С спецификация языка Java, Java SE 7 Edition,8.3.1.3. transient поля:

переменные могут быть обозначены transient to указывают, что они не являются частью постоянное состояние объекта.

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

здесь 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 метод.

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

источник

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

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

мой небольшой вклад :

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

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

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

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

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

null вместо этого, чтобы вы могли повторно инициализировать их с полезными данными, когда это необходимо.

transient используется для указания того, что поле класса не должно быть сериализовано. Вероятно, лучший пример-это

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

Я считаю, что образное значение модификатора " это поле предназначено только для использования в памяти. не сохраняйте и не перемещайте его за пределы этой конкретной виртуальной машины. Его непереносимо". т. е. вы не можете полагаться на его значение в другом пространстве памяти виртуальной машины. Очень нравится volatile означает, что вы не можете полагаться на определенную память и семантику потоков.

потому что не все переменные имеют сериализуемый характер

сериализация-это процесс сохранения состояний объекта в постоянном формате (например, файловый поток или база данных), а затем их восстановление из потока (де-сериализация). В Java объект класса сериализуем, если класс реализует интерфейс java.io.Serializable. Это интерфейс маркера, который сообщает JVM, что класс имеет право на сериализацию.

public class User implements Serializable {

    private static final long serialVersionUID = 1234L;

    private String username;
    private String email;
    private transient String password;
    private Date birthday;
    private int age;

    public User(String username, String email, String password, Date birthday,
            int age) {
        this.username = username;
        this.email = email;
        this.password = password;
        this.birthday = birthday;
        this.age = age;
    }

    public void printInfo() {
        System.out.println("username: " + username);
        System.out.println("email: " + email);
        System.out.println("password: " + password);
        System.out.println("birthday: " + birthday);
        System.out.println("age: " + age);
    }

    // getters and setters

}

в этом классе моделей есть три важных момента: Он должен реализует интерфейс Serializable. В противном случае мы получим исключение java.io.NotSerializableException при попытке сериализации объекта класса. Константа с именем serialVersionUID объявляется и присваивается длинное значение:

private static final long serialVersionUID = 1234L;

Это обычная константа, которая должна быть объявлена, когда класс реализует интерфейс Serializable. Uid последовательной версии строго обеспечивает совместимость между сериализованными и де-сериализованными версиями объектов класса, поскольку процесс сериализации и де-сериализации может происходить на разных компьютерах и системах. Хотя это объявление является необязательным, всегда рекомендуется объявлять serialVersionUID для сериализуемого класса.

обратите внимание, что поле пароля помечено как переходное:

private transient String password;

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

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

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

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

SPECIFIER/MODIFIER  LOCAL VARIABLE  INSTANCEVARIABLE    METHOD   CLASS
public              NA              A                   A         A
protected           NA              A                   A         NA
default             A               A                   A         A
private             NA              A                   A         NA
final               A               A                   A         A
static              NA              A                   A         NA
synchronized        NA              NA                  A         NA
native              NA              NA                  A         NA
volatile            NA              A                   NA        NA
transient           NA              A                   NA        NA
strictfp            NA              NA                  A         A

прежде чем я отвечу на этот вопрос, я должен объяснить вам сериализация, потому что если вы понимаете, что означает сериализация в science computer, вы можете легко понять это ключевое слово.

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

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

Теперь, если вы хотите, чтобы не TRANSFERT/спас поле этого объекта так, вы можете использовать ключевое словоtransient

private transient attr2;

пример

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

согласно google преходящее значение = = длится лишь короткое время; непостоянно.

теперь, если вы хотите сделать что-нибудь переходное в java, используйте ключевое слово transient.

Q: где использовать переходный процесс?

A: как правило, в java мы можем сохранять данные в файлы, получая их в переменных и записывая эти переменные в файлы, этот процесс известен как сериализация. Теперь, если мы хотим избежать записи переменных данных в файл, мы сделаем эту переменную как преходящий.

переходный результат int=10;

Примечание: переходные переменные не могут быть локальными.

проще говоря, ключевое слово transient java защищает поля от сериализации в качестве их непереходных полей встречных частей.

в этом фрагменте кода наш абстрактный класс BaseJob реализует сериализуемый интерфейс, мы расширяемся от BaseJob, но нам не нужно сериализовать удаленные и локальные источники данных; сериализовать только поля organizationName и 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;

   }
}