Dlaczego Java ma pola przejściowe?

Dlaczego Java ma pola transient ?

Author: RAnders00, 2009-05-26

13 answers

Słowo kluczowe transient w języku Java służy do wskazania, że pole nie powinno być serializowane.

Ze specyfikacji języka Java, Java SE 7 Edition, sekcja 8.3.1.3. transient Pola :

Zmienne mogą być oznaczone transient do wskazują, że nie są one częścią trwały stan obiektu.

Na przykład możesz mieć pola, które pochodzą z innych pól i powinny być wykonywane tylko programowo, a nie utrzymanie stanu poprzez serializację.

Oto klasa GalleryImage, która zawiera obrazek i miniaturkę pochodzącą z obrazu:

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();
    }    
}

W tym przykładzie, {[5] } jest miniaturą, która jest generowana przez wywołanie metody generateThumbnail.

Pole thumbnailImage jest oznaczone jako transient, więc tylko oryginalny image jest serializowany, a nie utrzymuje się zarówno oryginalnego obrazu, jak i miniatury. Oznacza to, że do zapisania seriali potrzeba mniej miejsca obiekt. (Oczywiście, może to być pożądane lub nie, w zależności od wymagań systemu-to tylko przykład.)

W czasie deserializacji,readObject metoda jest wywoływana do wykonywania wszelkich operacji niezbędnych do przywrócenia stanu obiektu z powrotem do stanu, w którym nastąpiła serializacja. Tutaj miniaturka musi zostać wygenerowana, więc metoda readObject jest nadpisana, aby miniaturka została wygenerowana przez wywołanie generateThumbnail metoda.

Aby uzyskać dodatkowe informacje, Artykuł Discover the secrets of the Java Serialization API (pierwotnie dostępny w Sun Developer Network) zawiera sekcję, która omawia użycie i przedstawia scenariusz, w którym słowo kluczowe transient jest używane do zapobiegania serializacji niektórych pól.

 1442
Author: coobird,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-05 06:19:33

Przed zrozumieniem słowa kluczowego transient należy zrozumieć pojęcie serializacji. Jeśli czytelnik wie o serializacji, proszę pominąć pierwszy punkt.

Co to jest serializacja?

Serializacja jest procesem, który sprawia, że stan obiektu jest trwały. Oznacza to, że stan obiektu jest konwertowany do strumienia bajtów i zapisywany w pliku. W ten sam sposób możemy użyć deserializacji, aby przywrócić stan obiektu z bajtów. Jest to jeden z ważne pojęcia w programowaniu Java, ponieważ serializacja jest używana głównie w programowaniu sieciowym. Obiekty, które muszą być transmitowane przez sieć, muszą zostać przekonwertowane na bajty. W tym celu każda klasa lub interfejs musi zaimplementować Serializable interfejs. Jest to interfejs znacznika bez żadnych metod.

Jakie jest słowo kluczowe transient i jego cel?

Domyślnie wszystkie zmienne obiektu są konwertowane do stanu trwałego. W niektórych przypadkach, możesz unikać utrzymywania niektórych zmiennych, ponieważ nie masz potrzeby utrzymywania tych zmiennych. Możesz więc zadeklarować te zmienne jako transient. Jeżeli zmienna jest zadeklarowana jako transient, to nie będzie ona utrzymywana. To jest główny cel słowa kluczowego transient.

Chcę wyjaśnić powyższe dwa punkty za pomocą następującego przykładu:

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);
    }
}

I wynik będzie następujący:

First Name : Steve
Middle Name : null
Last Name : Jobs

drugie imię jest zadeklarowane jako transient, więc nie będzie przechowywane w trwałe przechowywanie.

Źródło

 366
Author: Rahul Saxena,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-31 17:20:04

Aby umożliwić definiowanie zmiennych, których nie chcesz serializować.

W obiekcie możesz mieć informacje, których nie chcesz serializować/utrzymywać (być może odniesienie do nadrzędnego obiektu fabrycznego), lub być może serializacja nie ma sensu. Oznaczanie ich jako "przejściowe" oznacza, że mechanizm serializacji zignoruje te pola.

 80
Author: Brian Agnew,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-19 12:44:15

Mój mały wkład:

Czym jest pole przejściowe?
Zasadniczo każde pole zmodyfikowane słowem kluczowym transient jest polem przejściowym.

dlaczego w Javie potrzebne są pola przejściowe?
Słowo kluczowe transient daje pewną kontrolę nad procesem serializacji i pozwala wykluczyć niektóre właściwości obiektu z tego procesu. Proces serializacji jest używany do utrzymywania obiektów Java, głównie po to, aby ich Stany mogły być zachowane, gdy są przeniesione lub nieaktywne. Czasami sensowne jest nie serializowanie pewnych atrybutów obiektu.

które pola należy oznaczyć jako przejściowe?
Teraz znamy cel słowa kluczowego transient i pól przejściowych, ważne jest, aby wiedzieć, które pola oznaczyć jako przejściowe. Pola statyczne również nie są serializowane, więc odpowiednie słowo kluczowe również by pomogło. Ale to może zrujnować twój projekt klasowy; tutaj na ratunek przychodzi słowo kluczowe transient. Staram się nie pozwalać pola, których wartości mogą być wyprowadzone od innych do serializacji, więc zaznaczam je jako przejściowe. Jeśli masz pole o nazwie interest , którego wartość można obliczyć z innych pól (principal, rate & time), nie ma potrzeby serializacji.

Innym dobrym przykładem jest liczenie słów artykułów. Jeśli zapisujesz cały artykuł, naprawdę nie ma potrzeby zapisywania liczby słów, ponieważ można ją obliczyć, gdy artykuł zostanie " deserializowany."Albo pomyśl o loggerach; Logger instancje prawie nigdy nie muszą być serializowane, aby mogły być przemijające.

 28
Author: Shreyos Adikari,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-21 16:46:02

A transient zmienna jest zmienną, która nie może być serializowana.

Jednym z przykładów, kiedy może to być przydatne, jest to, że zmienne, które mają sens tylko w kontekście konkretnej instancji obiektu i które stają się nieważne po serializacji i deserializacji obiektu. W takim przypadku przydatne jest, aby te zmienne stały się null, aby w razie potrzeby można je ponownie zainicjować użytecznymi danymi.

 21
Author: Adrian Grigore,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-24 05:47:49

transient służy do wskazania, że pole klasy nie musi być serializowane. Prawdopodobnie najlepszym przykładem jest pole Thread. Zazwyczaj nie ma powodu do serializacji a Thread, ponieważ jego stan jest bardzo 'specyficzny dla przepływu'.

 13
Author: Andrei Ciobanu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-26 22:53:52

Systemy serializacji inne niż natywne java można również użyć tego modyfikatora. Na przykład Hibernate nie będzie utrzymywać pól oznaczonych albo @Transient , albo modyfikatorem transient . Terakota również szanuje ten modyfikator.

Myślę, że symboliczne znaczenie modyfikatora to " to pole jest przeznaczone tylko do użytku w pamięci. nie utrzymuj ani nie przenoś jej poza daną maszynę wirtualną w żaden sposób. Nie jest przenośny". tzn. nie można polegać na jego wartości w innej pamięci VM miejsce. Podobnie jak volatile oznacza, że nie można polegać na pewnej pamięci i semantyce wątku.

 10
Author: DragonFax,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-28 02:20:46

Ponieważ nie wszystkie zmienne mają charakter serializowalny

 9
Author: Silfverstrom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-26 12:15:38

Serializacja to proces zapisywania Stanów obiektu w trwałym formacie (takim jak strumień plików lub baza danych), a następnie przywracania ich ze strumienia (de-serializacja). W Javie obiekt klasy jest serializowalny, jeśli klasa implementuje interfejs java.io.Serializowalny. Jest to interfejs znacznika, który informuje JVM, że Klasa kwalifikuje się do serializacji.

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

}

Istnieją trzy ważne punkty w tej klasie modelu: Musi wdrażać Interfejs serializowalny. W przeciwnym razie otrzymamy wyjątek java.io.NotSerializableException podczas próby serializacji obiektu klasy. Stała o nazwie serialVersionUID jest deklarowana i przypisywana długiej wartości:

private static final long serialVersionUID = 1234L;

Jest to konwencjonalna stała, którą należy zadeklarować, gdy klasa implementuje interfejs Serializowalny. UID wersji szeregowej silnie zapewnia kompatybilność między serializowanymi i zdeserializowanymi wersjami obiektów klasy, ponieważ proces serializacji i de-serializacja może się zdarzyć na różnych komputerach i systemach. Chociaż ta deklaracja jest opcjonalna, zawsze zaleca się zadeklarowanie identyfikatora serialVersionUID dla klasy serializowalnej.

Zauważ, że pole hasła jest oznaczone jako przejściowe:

private transient String password;

Ponieważ nie chcemy przechowywać hasła podczas serializacji obiektu. Reguła jest taka, że gdy zmienna jest oznaczona jako transient, jej Obiekt nie będzie serializowany podczas serializacji.

Zmienna przejściowa {[8] } jest zmienna, która może nie być serializowana. Za pomocą słowa kluczowego transient można wskazać maszynie wirtualnej Java, że wskazana zmienna nie jest częścią stanu trwałego obiektu.

Modyfikatory dostępu obsługiwane przez Javę to statyczne, końcowe, abstrakcyjne, synchronizowane, natywne, volatile, transient i strictfp.

Poniższa tabela zawiera listę specyfikatorów i modyfikatorów dostępu Java, które można zastosować do zmiennych, metod i klas.

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
 9
Author: Zia,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-22 08:20:30

Zanim odpowiem na to pytanie, muszę ci wyjaśnićserializacja , ponieważ jeśli rozumiesz, co to znaczy serializacja w science computer, możesz łatwo zrozumieć to słowo kluczowe.

Serializacja Gdy obiekt jest przesyłany przez sieć / zapisywany na nośniku fizycznym (plik,...), obiekt musi być "serializowany". Serializacja konwertuje szereg obiektów stanu bajtów. Bajty te są wysyłane do sieci/zapisywane i obiekt jest ponownie tworzony z tych bajtów.
przykład

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

Teraz, jeśli chcesz NIE przenieść/zapisane pole tego obiektu więc , można użyć słowa kluczowego transient

private transient attr2;

Przykład

 6
Author: BERGUIGA Mohamed Amine,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:26:29

Jest potrzebny, gdy nie chcesz udostępniać poufnych danych, które idą z serializacją.

 3
Author: setzamora,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-26 12:19:31

Wg google znaczenie przejściowe = = trwające tylko przez krótki czas; nietrwałe.

Teraz, jeśli chcesz zrobić coś transientowego w Javie, użyj słowa kluczowego transient.

P: Gdzie używać transient?

A: generalnie w Javie możemy zapisywać dane do plików, pozyskując je w zmiennych i zapisując te zmienne do plików, proces ten znany jest jako serializacja. Teraz, jeśli chcemy uniknąć zapisywania zmiennych do pliku, zmienimy tę zmienną jako przejściową.

Transient int result = 10;

Uwaga: zmienne przejściowe nie mogą być lokalne.

 1
Author: Mateen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-02 08:56:39

Mówiąc najprościej, transient Java protect fields from the been Serialize as their non-transient fields counter parts.

W tym fragmencie kodu nasza abstrakcyjna klasa basejob implementuje interfejs Serializable, rozszerzamy z BaseJob, ale nie musimy serializować zdalnych i lokalnych źródeł danych; serializujemy tylko pola organizationName i 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;

   }
}
 1
Author: nyulan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-14 13:40:27