JavaRush /Java Blog /Random-TL /Paano Gumagana ang Serialization sa Java
ramhead
Antas

Paano Gumagana ang Serialization sa Java

Nai-publish sa grupo
Sa artikulong ito, ipapaliwanag namin kung ano ang serialization at kung paano ito gumagana sa Java. Как работает сериализация в Java - 1

Panimula

Ang Object serialization ay ang kakayahan ng isang bagay na mag-imbak ng kumpletong kopya ng sarili nito at anumang iba pang bagay na tinutukoy nito gamit ang isang output stream (halimbawa, sa isang panlabas na file). Sa ganitong paraan, maaaring muling likhain ang bagay mula sa serialized (naka-save) na kopya sa ibang pagkakataon kapag kinakailangan. Ang Object serialization, isang bagong feature na ipinakilala sa JDK 1.1, ay nagbibigay ng function para sa pag-convert ng mga grupo o indibidwal na object, sa isang bitstream o byte array, para sa storage o transmission sa isang network. At tulad ng nakasaad, ang isang naibigay na bit stream o byte array ay maaaring ma-convert pabalik sa Java object. Awtomatikong nangyayari ito dahil sa ObjectInputStreamat mga klase ObjectOutputStream. Maaaring magpasya ang programmer na ipatupad ang functionality na ito sa pamamagitan ng pagpapatupad ng interface Serializablekapag lumilikha ng klase. Ang proseso ng serialization ay kilala rin bilang object marshaling , habang ang deserialization ay kilala bilang unmarshaling . Ang serialization ay isang mekanismo na nagbibigay-daan sa isang bagay na mag-save ng isang kopya ng sarili nito at lahat ng iba pang mga bagay na isinangguni ng bagay na iyon sa isang panlabas na file gamit ang ObjectOutputStream. Ang mga na-save na bagay ay maaaring mga istruktura ng data, mga diagram, mga bagay sa klase JFrame, o anumang iba pang mga bagay, anuman ang kanilang uri. Kasabay nito, ang serialization ay nag-iimbak ng impormasyon tungkol sa kung anong uri ang isang bagay upang sa paglaon, kapag na-deserialize, ang impormasyong iyon ay ginagamit upang muling likhain ang eksaktong uri ng bagay na iyon. Kaya, ang serialization ay nagbibigay ng mga sumusunod na kakayahan:
  • Isang sistema para sa pag-iimbak ng mga bagay, i.e.: pag-save ng kanilang mga katangian sa isang panlabas na file, sa disk o sa isang database.
  • Remote procedure call system.
  • Isang object distribution system, halimbawa, sa mga bahagi ng software tulad ng COM, COBRA.
  • System para sa pagtukoy ng mga pagbabago sa variable na data sa paglipas ng panahon.
Upang lubos na maunawaan ang konsepto ng serialization, kailangan mong magkaroon ng malinaw na pag-unawa sa iba pang dalawang konsepto—pagtitiyaga ng object at pagtitiyaga ng thread. Dito ay pag-uusapan natin ang bawat isa sa kanila upang matandaan. Ang isang buong paliwanag sa mga ito ay mangangailangan ng isang hiwalay na kabanata para sa bawat isa sa mga konseptong ito.

Batis:

Dapat isulat ng bawat program ang data nito sa lokasyon ng storage o pipe, at dapat basahin ng bawat program ang data mula sa pipe o lokasyon ng storage. Sa Java, ang mga channel na ito kung saan sumusulat ang mga program at kung saan nagbabasa ng data ang mga program ay tinatawag na Streams ( Stream) . Как работает сериализация в Java - 2
Figure 1. Graphical na representasyon ng mga Thread
Ang mga stream ay pangunahing nahahati sa dalawang uri:
  • Mga klase ng byte stream na tinatawag na *Streams
  • Mga klase ng stream ng character na tinatawag na *Reader at *Writer
Ang bawat stream ng pagsulat ng data ay naglalaman ng isang hanay ng mga paraan ng pagsulat. At ang bawat thread ng pagbabasa ng data, nang naaayon, ay may katulad na hanay ng mga paraan ng pagbabasa. Kapag nalikha ang thread, dapat na tawagan ang lahat ng mga pamamaraang ito.

Pagtitiyaga

Персистентность an object это способность обекта жить or по-другому - "пережить" выполнение программы. Это значит, что любой an object, который был создан во времени выполнения, уничтожается "мусорщиком" JVM, всякий раз, когда данный an object далее перестает использоваться. Но в случае реализации API персистентности, данные an objectы не будут уничтожаться "мусорщиком" JVM, instead of чего им будет позволено "жить", что также дает возможность доступа к ним при следующем запуске applications. Другими словами, персистенция означает существование времени жизни an object, независимо от времени жизни applications, которое запущено. Один из способов реализации персистентности это хранение an objectов где-нибудь во внешнем файле or в базе данных, а затем восстановление их в более позднее время, используя данные файлы or базу данных How источники. Здесь сериализация и вступает в игру. Любой неперсистентный an object существует так долго, How долго работает JVM. Сериализованные an objectы — это просто an objectы, преобразованные в потоки, которые затем сохраняются во внешний файл or передаются через сеть для хранения и восстановления.

Реализация интерфейса Serializable

Любой класс должен реализовывать интерфейс java.io.Serializable для сериализации an objectов этого класса. Интерфейс Serializable не имеет методов и только маркерует класс, чтобы можно было идентифицировать его How сериализуемый. Только поля an object сериализованного класса могут быть сохранены. Методы or конструкторы не сохраняются, How части сериализованного потока. Если Howой-либо an object действует How link на другой an object, то поля этого an object также сериализованны, если класс этого an object реализует интерфейс Serializable. Другими словам, получаемый таким образом граф этого an object, сериализуем fully. Граф an object включает дерево or структуру полей an object и его подan objectов. Два главных класса, которые помогают реализовать интерфейс Seriliazable:
  • ObjectInputStream
  • ObjectOutputStream
Листинг 1. Пример простого класса, чтобы показать сериализацию
import java.io.*;
public class RandomClass implements Serializable {
 // Генерация рандомного значения
 private static int r() {
        return (int)(Math.random() * 10);
 }
    private int data[];
    // Конструктор
public RandomClass() {
        datafile = new int[r()];
        for (int i=0; i<datafile.length; i++)
        datafile[i]=r();
 }
    public void printout() {
 System.out.println("This RandomClass has "+datafile.length+" random integers");
 for (int i=0; i<datafile.length; i++) {
        System.out.print(datafile[i]+":");
        System.out.println();
    }
}
В приведенном выше codeе, создается класс, который является сериализуемым, т.к. "промаркерован" интерфейсом сериализации. Класс создает массив случайных целых чисел, когда создается его экземпляр. Приведенный ниже code, показывает возможность записи an objectов в поток, используя класс ObjectOutputStream. Программа имеет массив целых чисел, но для сериализации мы не должны перебирать ее внутренние an objectы. Интерфейс Seriliazable заботится об этом автоматически. Листинг 2. Простой пример сериализации an objectов для вывода в файл
import java.io.*;
import java.util.*;
public class OutSerialize {
    public static void main (String args[]) throws IOException {
        RandomClass rc1 = new RandomClass();
        RandomClass rc2 = new RandomClass();
//создание цепи потоков с потоком вывода an object в конце
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("objects.dat"));
        Date now = new Date(System.currentTimeMillis());
//java.util.* был импортирован для использования класса Date
        out.writeObject(now);
        out.writeObject(rc1);
        out.writeObject(rc2);
out.close();
        System.out.println("I have written:");
System.out.println("A Date object: "+now);
        System.out.println("Two Group of randoms");
rc1.printout();
rc2.printout();
 }
}
Код ниже демонстрирует возможности класса ObjectInputStream, который считывает сериализованные данные с внешнего file, в программу. Заметьте, что an objectы считываются в том же порядке, в котором были записаны в файл. Листинг 3. Чтение сериализованных an objectов or Десериализация
import java.io.*;
import java.util.*;
public class InSerialize {
 public static void main (String args[]) throws  IOException, ClassNotFoundException {
    ObjectInputStream in =  new ObjectInputStream (new FileInputStream("objects.dat"));
 Date d1 = (Date)in.readObject();
 RandomClass rc1 = (RandomClass)in.readObject();
    RandomClass rc2 = (RandomClass)in.readObject();
    System.out.println("I have read:");
    System.out.println("A Date object: "+d1);
    System.out.println("Two Group of randoms");
    rc1.printout();
rc2.printout();
 }
}
Почти все классы Java могут быть сериализованны, включая классы AWT. Фрейм, который является окном, содержит набор графических компонентов. Если фрейм сериализован, механизм сериализации заботится об этом и сериализует все его компоненты и данные(позицию, содержание и т.д.). Некоторые an objectы классов Java, не могут быть сериализованы, потому что содержат данные, что ссылаются на кратковременные ресурсы операционных систем. Например классы java.io.FileInputStream и java.lang.Thread. Если an object содержит ссылки на несериализуемые элементы, вся операция сериализации потерпит неудачу и будет выброшено исключение NotSerializableException. Если Howой-либо an object ссылается на ссылку несериализованного an object, то его можно сериализовать используя ключевое слово transient. Листинг 4. Creation сериализуемых an objectов используя ключево слово transient
public class Sclass implements Serializable{
public transient Thread newThread;
//помните, что поток(поток параллельного исполнения) по умолчанию не сериализуемый класс
    private String studentID;
    private int sum;
}

Безопасность в Сериализации

Сериализация класса в Java, подразумевает передачу всех его данных во внешний файл or базу данных через поток. Мы можем ограничить данные, которые будут сериализованны, когда того пожелаем. Есть два способа сделать это:
  • Каждый параметр класса объявленный How transient, не сериализуются(по умолчанию все параметры класса сериализуются)
  • Или каждый параметр класса, который мы хотим сериализовать, помечается тегом Externalizable (по умолчанию ниHowие параметры не сериализуются).
Поле данных не будет сериализовано с помощью ObjectOutputStream, когда оно будет вызвано для an object, если это поле данных, данного an object помечено How transient. Например: private transient String password. С другой стороны, для явного объявления данных an object How сериализуемых, мы должны промаркировать класс How ExternalizablewriteExternal и readExteranl для записи и чтения данных этого an object явно.

Заключение

Особенность сериализации оъектов использована во многих распределенных системах, How способ передачи данных. Но сериализация раскрывает скрытые детали, таким образом разрушая подлинность абстрактных типов данных, что в свою очередь разрушает инкапсуляцию. В тоже время приятно знать, что данные сериализованного an object, те же самые данные, что были в исходном, оригинальном an objectе. Это также отличная возможность для реализации интерфейса ObjectInputValidation и переопределения метода validateObject(), даже если ипользуются несколько строк codeа. Если an object не найден, то мы можем надлежащим образом выбросить исключение InvalidObjectException. Оригинал статьи: How serialization works in Java
Mga komento
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION