Каква е концепцията за сериализация в Java?



Тази статия ще ви помогне с цялостен подход към концепцията за сериализация в Java, заедно с примери в реално време за по-добро разбиране.

Сериализация в е важна концепция, която се занимава с преобразуването на обекти в байтов поток, за да транспортира java обектите от една Java Virtual Machine до другата и да ги пресъздаде в оригиналната форма. Ще подредя документацията за тази статия, както е показано по-долу:

Какво е сериализация в Java?

Сериализация в Java е процесът на конвертиране на Java кода Обект в a Байтов поток , за да прехвърлите обектния код от една Java виртуална машина на друга и да го пресъздадете с помощта на процеса на Десериализация.





Serialization-in-Java-Edureka-Picture-1

Защо се нуждаем от сериализация в Java ?

Нуждаем се от сериализация по следните причини:



  • Комуникация : Сериализацията включва процедурата на обекта сериализация и предаване. Това позволява на множество компютърни системи да проектират, споделят и изпълняват обекти едновременно.

  • Кеширане : Времето, изразходвано за изграждане на обект, е повече в сравнение с времето, необходимо за неговата десериализация. Сериализацията минимизира консумацията на време от кеширане гигантските обекти.

  • Дълбоко копиране : Клониране процесът е опростен с помощта на сериализация. Точно реплика на обект се получава чрезсериализиране на обекта към a байтов масив и след това го десериализира.



  • Кръст JVM синхронизация: Основното предимство на сериализацията е, че тяработи в различни JVM, които може да работят на различни архитектури или Операционна система

  • Устойчивост: Състоянието на всеки обект може директно да се съхранява чрез прилагане на сериализация върху него и да се съхранява в база данни за да може да бъде извлечен по-късно.

Как да сериализираме обект?

ДА СЕ Java обект е сериализуем ако и само ако неговият клас или някой от родителските му класове изпълняват или java . Аз . Сериализуемо интерфейс или негов подинтерфейс, java.io.Екстернализируем.

В процеса на сериализация ние преобразуваме състоянието на обекта в байтов поток, за да може той да бъде прехвърлен от един JVM в другия и да върнем байтовия поток обратно в оригиналния обект.

// Интерфейс

пакет Serial1 import java.io.Serializable публичен клас Служител реализира Serializable {private static final long serialVersionUID = 1L // Serial Version UID int id Име на низ public Employee (int id, String name) {this.id = id this.name = name }}

// Сериализиране

python преобразува числото в двоично
пакет Serial1 import java.io. * class Persist {public static void main (String args []) {try {Служител emp1 = нов служител (20110, 'John') Служител emp2 = нов служител (22110, 'Jerry') Служител emp3 = нов служител (20120, 'Sam') FileOutputStream fout = new FileOutputStream ('output.txt') ObjectOutputStream out = new ObjectOutputStream (fout) out.writeObject (emp1) out.writeObject (emp2) out.writeObject (emp3) out. flush () out.close () System.out.println ('Сериализацията и десериализацията са изпълнени успешно')} catch (Изключение e) {System.out.println (e)}}}

Изход:

Сериализацията и десериализацията са изпълнени успешно

Десериализация : Това е обратният процес на сериализация, при който сериализираният байтов поток на обект от подателя се пресъздава в приемащия край.

// Десериализиране

пакет Serial1 import java.io. * class Depersist {public static void main (String args []) {try {ObjectInputStream in = new ObjectInputStream (new FileInputStream ('output.txt')) Служител e1 = (Служител) in.readObject ( ) Служител e2 = (Служител) in.readObject () Служител e3 = (Служител) in.readObject () System.out.println (e1.id + '+ e1.name) System.out.println (e2.id +' ' + e2.name) System.out.println (e3.id + '' + e3.name) in.close ()} catch (Изключение e) {System.out.println (e)}}}

Изход:

20110 Джон
22110 Джери

20120 Сам

Предимства и недостатъци на сериализацията в Java

Предимства:

  • Процесът на сериализация е a вграден функция, която не изисква софтуер на трета страна за изпълнение на сериализация
  • Доказано е, че процедурата за сериализация е такава просто и лесно да разбера

  • Процедурата за сериализиране е универсален и разработчиците от различен произход са му познати

  • Той е лесен за използване и лесен за персонализиране

  • Сериализирани потоци от данни поддържа шифроване, компресия, удостоверяване и защитени Java изчисления

  • Има много критични технологии разчита на сериализация.

Недостатъци:

  • Обекти докато DeSerialization става крехък и те не са сигурни, че ще бъдат ефективно десериализирани.

  • Преходните променливи, декларирани докато сериализацията създава място в паметта, но конструкторът не се извиква, което води до неуспех в инициализацията на преходни променливи, което води до вариация на стандартния Java Flow.

  • Процесът на сериализация е неефикасен по отношение на използването на паметта.

  • Сериализацията не е за предпочитане да се използва в приложенията, които се нуждаят едновременен достъп без изискването на API на трети страни , тъй като сериализацията не предлага механизъм за контрол на прехода за всяка SE.

  • Процедурата за сериализация не предлага фино контролиран контрол за достъп до Обекти.

Практически примери за сериализация в Java

Сериализация с използване на наследство

Случай - 1: Ако Superclass е сериализуем, тогава по подразбиране неговите подкласове също могат да се сериализират.

В този случай подклас е сериализуем по подразбиране, ако суперклас изпълнява Сериализуем интерфейс

пакет SerializationInheritance import java.io.FileInputStream import java.io.FileOutputStream import java.io.ObjectInputStream import java.io.ObjectOutputStream import java.io.Serializable class A implements Serializable {int i public A (int i) {this.i = i}} клас B разширява A {int j public B (int i, int j) {super (i) this.j = j}} тест за публичен клас {public static void main (String [] args) хвърля изключение {B b1 = нов B (200 400) System.out.println ('i =' + b1.i) System.out.println ('j =' + b1.j) FileOutputStream fos = нов FileOutputStream ('abc.ser') ObjectOutputStream oos = new ObjectOutputStream (fos) oos.writeObject (b1) oos.close () fos.close () System.out.println ('Обектът е сериализиран') FileInputStream fis = new FileInputStream ('abc.ser') ObjectInputStream ois = new ObjectInputStream (fis) B b2 = (B) ois.readObject () ois.close () fis.close () System.out.println ('Обектът е десериализиран') System.out.println ('i = '+ b2.i) System.out.println (' j = '+ b2.j)}}

Изход:

j = 20
Обектът е сериализиран
Обектът е десериализиран
i = 200
j = 400

Случай - 2: Подклас може да бъде сериализиран, ако той изпълнява сериализуем интерфейс, дори ако суперкласът не реализира сериализуем интерфейс.

В този случай, ако суперклас не прилага Сериализуем интерфейс , след това обектите на подклас могат да бъдат ръчно сериализирани чрез внедряване на сериализуем интерфейс в подкласа.

пакет SerializationInheritance import java.io.FileInputStream import java.io.FileOutputStream import java.io.ObjectInputStream import java.io.ObjectOutputStream import java.io.Serializable class superclass {int i public superclass (int i) {this.i = i} публичен суперклас () {i = 50 System.out.println ('Конструктор на суперклас, наречен')}} клас подклас разширява суперклас изпълнява Сериализуем {int j публичен подклас (int i, int j) {super (i) this.j = j }} публичен клас test2 {public static void main (String [] args) хвърля изключение {подклас b1 = нов подклас (10, 20) System.out.println ('i =' + b1.i) System.out.println ( 'j =' + b1.j) FileOutputStream fos = new FileOutputStream ('output.ser') ObjectOutputStream oos = new ObjectOutputStream (fos) oos.writeObject (b1) oos.close () fos.close () System.out.println ('Обектът е сериализиран') FileInputStream fis = нов FileInputStream ('output.ser') ObjectInputStream ois = нов ObjectInputStream (fis) подклас b2 = (подклас) ois.readObject ( ) ois.close () fis.close () System.out.println ('Обектът е десериализиран') System.out.println ('i =' + b2.i) System.out.println ('j =' + b2.j)}}

Обектът е сериализиран
Извикан конструктор на суперклас
Обектът е десериализиран
i = 50
j = 20

Случай - 3: Ако суперкласът е сериализуем, но не е необходимо подкласът да бъде сериализиран.

В този случай може да се предотврати сериализацията на подкласачрез прилагане на writeObject () и readObject () методи в подкласа и той трябва да хвърли NotSerializableException от тези методи.

пакет SerializationInheritance import java.io.FileInputStream import java.io.FileOutputStream import java.io.IOException import java.io.NotSerializableException import java.io.ObjectInputStream import java.io.ObjectOutputStreamliza import java.iorent Parent. i public Parent (int i) {this.i = i}} клас дете разширява Parent {int j public child (int i, int j) {super (i) this.j = j} private void writeObject (ObjectOutputStream out) хвърля IOException {хвърли нов NotSerializableException ()} private void readObject (ObjectInputStream in) хвърля IOException {хвърли нов NotSerializableException ()}} публичен клас test3 {public static void main (String [] args) хвърля изключение {дете b1 = ново дете (100, 200) System.out.println ('i =' + b1.i) System.out.println ('j =' + b1.j) FileOutputStream fos = new FileOutputStream ('abc.ser') ObjectOutputStream oos = new ObjectOutputStream ( fos) oos.writeObject (b1) oos.close () fos.close () System.out.println ('Обект е сериализиран ') FileInputStream fis = нов FileInputStream (' abc.ser ') ObjectInputStream ois = нов ObjectInputStream (fis) дете b2 = (дете) ois.readObject () ois.close () fis.close () System.out. println ('Обектът е десериализиран') System.out.println ('i =' + b2.i) System.out.println ('j =' + b2.j)}}

Изход:

i = 100
j = 200
Изключение в нишката 'main' java.io.NotSerializableException
при SerializationInheritance.child.writeObject (test3.java:48)
at sun.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)

Сериализация с помощта на статичен член

В процеса на сериализация сериализацията на статичното поле на член се игнорира. Сериализацията есвързани с последното състояние на обекта. Следователно само данните, свързани с конкретен екземпляр на клас, сасериализирано, но не и полето Статичен член.

пакет стати импортиране java.io. * клас StaticSerial реализира Serializable {static int i = 100 публична статична void main (String ... ar) {StaticSerial ob = new StaticSerial () System.out.println ('По време на сериализацията, статичният член има стойност: '+ i) опитайте {FileOutputStream fos = new FileOutputStream (' F: File.ser ') ObjectOutputStream oos = new ObjectOutputStream (fos) oos.writeObject (ob) oos.close () i = 99 FileInputStream fis = new FileInputStream ('F: File.ser') ObjectInputStream ois = new ObjectInputStream (fis) ob = (StaticSerial) ois.readObject () ois.close () System.out.println ('След десериализация статичният член има стойност:' + i)} catch (Изключение e) {System.out.println (e)}}}

Изход:

По време на сериализацията статичният член има стойност: 100
След десериализация статичният член има стойност: 99

Външен интерфейс

The Външен интерфейс в Java е подобен на сериализацията, но единствената разлика е, че е в състояние да предложи персонализирана сериализация където можете да решите обектите, които ще бъдат разбити в потока.

Интерфейсът Externalizable е достъпен в java.io и предоставя два метода:

  • public void writeExternal (ObjectOutput out) хвърля IOException
  • public void readExternal (ObjectInput in) изхвърля IOException

Основните разлики между сериализацията и Externalizeable са както следва:

  • Изпълнение : Externalizable Interface изключва потребителя до изрично споменете обектите, които ще бъдат сериализирани. Докато са в интерфейса за сериализация, всички обекти и променливи са сериализирани в време на изпълнение.

  • Методи : Външният интерфейс се състои от два метода, а именно:

    • writeExternal ()

    • readExternal ()

Докато Serializable Interface не включва никакви методи.

  • Процес: Процесът на сериализация в Externalizable Interface осигурява персонализиране към процеса на сериализация. Но интерфейсът за сериализация ще осигури по подразбиране процес на сериализация.

  • Обратна съвместимост и контрол: Externalizable Interface поддържа сериализация независимо от контрол на версиите и единственият проблем е, че потребителят трябва да носи отговорност, докато сериализира Super Class. От друга страна, интерфейсът за сериализация изисква същата версия на JVM в двата края, но включва автоматична сериализация на всички обекти и класове, включително суперкласа.

  • Публичен No-Arg конструктор: Нужди от интерфейс за екстернализация Публичен No-Arg конструктор за реконструкция на сериализирания обект. Докато интерфейсът за сериализация не изисква конструктор No-Arg, вместо това той използва отражение за реконструкция на сериализирания обект или клас.

пакет външен импорт java.io. * клас Демо реализира java.io.Serializable {public int a public String b public Demo (int a, String b) {this.a = a this.b = b}} Class test {public static void main (String [] args) {Demo object = new Demo (1, 'Welcome to Edureka') String filename = 'file.ser' try {FileOutputStream file = new FileOutputStream (filename) ObjectOutputStream out = new ObjectOutputStream (file) out .writeObject (обект) out.close () file.close () System.out.println ('Обектът е сериализиран')} catch (IOException ex) {System.out.println ('IOException is catch')} Demo object1 = null try {FileInputStream file = new FileInputStream (filename) ObjectInputStream in = new ObjectInputStream (file) object1 = (Demo) in.readObject () in.close () file.close () System.out.println ('Обектът е бил десериализиран ') System.out.println (' a = '+ object1.a) System.out.println (' b = '+ object1.b)} catch (IOException ex) {System.out.println (' IOException is catch ')} catch (ClassNotFoundException ex) {System.out .println ('ClassNotFoundException е уловен')}}}

Преходна ключова дума

Преходната ключова дума е a запазена ключова дума в Java. Използва се като a променлива промяна по време на процеса на сериализация. Декларирането на променлива с ключова дума Transient избягва променливата да бъде сериализирана.

урок за големи данни за начинаещи

UID на серийната версия

Преди да започне процесът на сериализация, всеки сериализуем клас / обект се свързва с a уникален идентификационен номер предоставено от JVM на хост машината. Този уникален идентификатор се извиква UID на серийната версия . Този UID се използва като идентификация от JVM на приемащия край, за да потвърди, че същият обект се десериализира в приемащия край.

Противоречия на сериализацията в Java

Oracle’s Архитектите възнамеряват да премахнат сериализацията от Java, тъй като я смятат за Ужасна грешка от 1997 г. . След забързано проучване разработчиците в Oracle откриха няколко недостатъка в дизайна на процедурата за сериализация, които представляват заплаха за данните.

През 1997 г.Марк Рейнхолд заявява - “ Обичаме да наричаме сериализацията „подаръкът, който продължава да дава“, а видът подарък, който продължава да дава, е уязвимостта на сигурността. Вероятно една трета от всички уязвимости на Java включват сериализация, може да е над половината. Това е удивително плодов източник на уязвимости, да не говорим за нестабилности. ”.

Има шансове сериализацията да бъде премахната или заменена в предстоящите актуализации на Java, а от друга страна, за начинаещи в Java, сериализация Не можех бъде идеалистичен вариант в техните проекти

Най-добри практики при използване на сериализация в Java

Следват няколко най-добри практики, които трябва да се следват

  • Препоръчва се употреба javadoc @ сериен маркер за обозначаване на сериализуеми полета.
  • The .да бъде разширението се предпочита да се използва за файлове, представляващи сериализирани обекти.
  • Не се препоръчва преминаването на статични или преходни полета сериализация по подразбиране.
  • Разширяващи се класове не трябва да се сериализира, освен ако не е задължителен.
  • Вътрешни класове трябва да се избягва участието в сериализацията.

С това стигнахме до края на тази статия. Надявам се, че сте разбрали основите на сериализацията в Java, нейните типове и неговите функционалности.

Вижте от Edureka, доверена компания за онлайн обучение с мрежа от над 250 000 доволни учащи, разпространени по целия свят. Курсът за обучение и сертифициране на Java J2EE и SOA на Edureka е предназначен за студенти и професионалисти, които искат да бъдат Java Developer. Курсът е предназначен да ви даде начален старт в програмирането на Java и да ви обучи както за основните, така и за разширените Java концепции, заедно с различни Java рамки като Hibernate & Пролет .

Имате въпрос към нас? Споменете го в раздела за коментари в тази статия „Сериализация в Java“ и ние ще се свържем с вас възможно най-скоро.