JavaRush /Блоги Java /Random-TG /Сериализатсия ҳамон тавре ки ҳаст. Қисми 1
articles
Сатҳи

Сериализатсия ҳамон тавре ки ҳаст. Қисми 1

Дар гурӯҳ нашр шудааст
Дар назари аввал сериализатсия як раванди ночиз ба назар мерасад. Дар ҳақиқат, чӣ метавонад соддатар бошад? Синфро барои татбиқи интерфейс эълон кард java.io.Serializable- ва ҳамин тавр. Шумо метавонед синфро бе мушкилот сериал кунед. Сериализатсия ҳамон тавре ки ҳаст.  Қисми 1 - 1Аз ҷиҳати назариявӣ, ин дуруст аст. Дар амал бисьёр нозукихо мавчуданд. Онҳо ба иҷроиш, бесериясозӣ ва бехатарии синф алоқаманданд. Ва бо бисёр ҷанбаҳои дигар. Чунин нозукиҳо муҳокима хоҳанд шуд. Ин мақоларо метавон ба қисмҳои зерин тақсим кард:
  • Нозукихои механизмхо
  • Чаро он лозим аст?Externalizable
  • Намоиш
  • балки аз тарафи дигар
  • Амнияти маълумот
  • Сериализатсияи an objectSingleton
Биёед ба қисми аввал гузарем -

Нозукихои механизмхо

Пеш аз ҳама, як саволи зуд. Барои сериализатсия кардани an object чанд роҳ вуҷуд дорад? Амалия нишон медиҳад, ки зиёда аз 90% таҳиягарон ба ин савол тақрибан як хел ҷавоб медиҳанд (то ба матн) - танҳо як роҳ вуҷуд дорад. Дар ҳамин ҳол, ду нафари онҳо ҳастанд. Дуюмро на ҳама дар ёд доранд, бигзор дар бораи хусусиятҳояш чизе фаҳмо бигӯяд. Пас, ин усулҳо чист? Аввалинро ҳама дар хотир доранд. Ин татбиқи аллакай зикршуда аст java.io.Serializableва ҳеҷ гуна кӯшишро талаб намекунад. Усули дуюм инчунин татбиқи интерфейс аст, аммо дигараш: java.io.Externalizable. Баръакси java.io.Serializable, он дорои ду усулест, ки бояд амалӣ карда шаванд - writeExternal(ObjectOutput)ва readExternal(ObjectInput). Ин усулҳо мантиқи сериализатсия/сериализатсияро дар бар мегиранд. Шарҳ.SerializableДар оянда , ман баъзан ба сериализатсия бо татбиқ ҳамчун стандарт ва татбиқ Externalizableҳамчун васеъ муроҷиат хоҳам кард. Дигаршарҳ. Ман дидаву дониста ҳоло ба чунин вариантҳои стандартии идоракунии сериализатсия дахл намекунам, ба монанди муайян кардан readObjectва writeObject, зеро Ман фикр мекунам, ки ин усулҳо то андозае нодурустанд. Ин усулҳо дар интерфейс муайян карда нашудаанд Serializableва дар асл, барои кор кардан дар атрофи маҳдудиятҳо ва чандир кардани силсилаи стандартӣ мебошанд. ExternalizableУсулҳое, ки чандириро таъмин мекунанд, дар онҳо аз ибтидо сохта шудаанд . Биёед боз як савол диҳем. Чӣ тавр сериализатсияи стандартӣ бо истифода аз java.io.Serializable? Ва он тавассути API Reflection кор мекунад. Онхое. синф ҳамчун маҷмӯи майдонҳо таҳлил карда мешавад, ки ҳар яки онҳо ба ҷараёни баромад навишта мешаванд. Ба фикрам маълум аст, ки ин амалиёт аз чихати кор оптималй нест. Мо баъдтар аниқ хоҳем кард. Дар байни ду усули сериализатсия, ки дар боло зикр шудаанд, фарқияти дигари калон вуҷуд дорад. Махз, дар механизми десериализация. Ҳангоми истифода, Serializableбесериализатсия чунин сурат мегирад: хотира барои an object ҷудо карда мешавад, ки пас аз он майдонҳои он бо арзишҳои ҷараён пур карда мешаванд. Конструктори an object даъват карда намешавад. Дар ин ҷо мо бояд ин вазъиятро алоҳида баррасӣ кунем. Хуб, синфи мо сериализатсия карда мешавад. Ва падару модараш? Комилан ихтиёрӣ! Гузашта аз ин, агар шумо синферо аз мерос гиред Object- волидайн бешубҳа серия кардан НЕСТ. Ва гарчанде ки Objectмо дар бораи соҳаҳо чизе намедонем, онҳо метавонанд дар синфҳои волидайни худи мо вуҷуд дошта бошанд. Бо онҳо чӣ мешавад? Онҳо ба ҷараёни сериализатсия ворид намешаванд. Ҳангоми бесериализатсия онҳо кадом арзишҳоро мегиранд? Биёед ба ин мисол назар андозем:
package ru.skipy.tests.io;

import java.io.*;

/**
 * ParentDeserializationTest
 *
 * @author Eugene Matyushkin aka Skipy
 * @since 05.08.2010
 */
public class ParentDeserializationTest {

    public static void main(String[] args){
        try {
            System.out.println("Creating...");
            Child c = new Child(1);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(baos);
            c.field = 10;
            System.out.println("Serializing...");
            oos.writeObject(c);
            oos.flush();
            baos.flush();
            oos.close();
            baos.close();
            ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(bais);
            System.out.println("Deserializing...");
            Child c1 = (Child)ois.readObject();
            System.out.println("c1.i="+c1.getI());
            System.out.println("c1.field="+c1.getField());
        } catch (IOException ex){
            ex.printStackTrace();
        } catch (ClassNotFoundException ex){
            ex.printStackTrace();
        }
    }

    public static class Parent {
        protected int field;
        protected Parent(){
            field = 5;
            System.out.println("Parent::Constructor");
        }
        public int getField() {
            return field;
        }
    }

    public static class Child extends Parent implements Serializable{
        protected int i;
        public Child(int i){
            this.i = i;
            System.out.println("Child::Constructor");
        }
        public int getI() {
            return i;
        }
    }
}
Ин шаффоф аст - мо як синфи волидайни сериализатсиянашаванда ва синфи кӯдаки сериализатсияшаванда дорем. Ва ин аст он чизе ки рӯй медиҳад:
Creating...
Parent::Constructor
Child::Constructor
Serializing...
Deserializing...
Parent::Constructor
c1.i=1
c1.field=5
Яъне, ҳангоми бесериализатсия конструктор бе параметрҳои синфи волидайни NON-serializable номида мешавад . Ва агар чунин созанда вуҷуд надошта бошад, ҳангоми бекоркунӣ хатогӣ рух медиҳад. Конструктори an objectи кўдак, ки мо бесавод карда истодаем, тавре ки дар боло гуфта шуд, даъват карда намешавад. Ҳангоми истифода механизмҳои стандартӣ ҳамин тавр рафтор мекунанд Serializable. Ҳангоми истифодаи он Externalizableвазъият дигар аст. Аввал конструктори бе параметр даъват карда мешавад ва баъд ба an objectи сохташуда усули readExternal даъват карда мешавад, ки воқеан тамоми маълумоти онро мехонад. Аз ин рӯ, ҳама синфе, ки интерфейси Externalizable-ро амалӣ мекунад, бояд конструктори оммавиро бидуни параметр дошта бошад! Гузашта аз ин, азбаски ҳамаи наслҳои чунин синфҳо инчунин барои татбиқи интерфейс баррасӣ мешаванд Externalizable, онҳо инчунин бояд конструктори бепараметр дошта бошанд! Биёед минбаъд равем. Чунин тағирдиҳандаи майдон вуҷуд дорад, ба монанди transient. Ин маънои онро дорад, ки ин майдон набояд серия карда шавад. Аммо, чунон ки шумо худатон мефаҳмед, ин дастур танҳо ба механизми стандартии сериализатсия таъсир мерасонад. Ҳангоми истифода, Externalizableҳеҷ кас барои сериал кардани ин майдон ва инчунин тарҳ кардани он ташвиш намедиҳад. Агар майдон муваққатӣ эълон шуда бошад, пас вақте ки an object ғайрисериявӣ мешавад, он арзиши пешфарзро мегирад. Боз як нуктаи хеле нозук. Бо силсиласозии стандартӣ, майдонҳое, ки тағирдиҳанда доранд, staticсериализатсия карда намешаванд. Мутаносибан, пас аз бесериясозӣ ин майдон арзиши худро тағир намедиҳад. Албатта, ҳангоми татбиқ, Externalizableҳеҷ кас барои сериализатсия ва бесариализатсияи ин соҳа ташвиш намедиҳад, аммо ман тавсия медиҳам, ки ин корро накунед, зеро ин метавонад ба хатогиҳои нозук оварда расонад. Майдонҳо бо тағирдиҳанда finalмисли майдонҳои муқаррарӣ силсилавӣ карда мешаванд. Ба истиснои як истисно - онҳо ҳангоми истифодаи Externalizable ғайрифаъол карда намешаванд. Зеро final-поляонҳо бояд дар конструктор оғоз карда шаванд ва баъд аз он тағир додани арзиши ин майдон дар readExternal ғайриимкон хоҳад буд. Мутаносибан, агар ба шумо лозим аст, ки an objectи дорои final-майдонро сериализатсия кунед, шумо бояд танҳо силсилаи стандартиро истифода баред. Нуктаи дигаре, ки бисёриҳо намедонанд. Сериализатсияи стандартӣ тартиби дар синф эълон шудани майдонҳоро ба назар мегирад. Дар ҳар сурат, дар versionҳои қаблӣ чунин буд; дар versionи JVM 1.6 татбиқи Oracle, тартиб дигар муҳим нест, намуд ва номи майдон муҳим аст. Таркиби усулҳо эҳтимол дорад, ки ба механизми стандартӣ таъсир расонад, сарфи назар аз он, ки майдонҳо метавонанд умуман якхела бошанд. Барои пешгирӣ кардани ин, механизми зерин вуҷуд дорад. Ба ҳар як синфе, ки интерфейсро амалӣ мекунад Serializable, дар марҳилаи компиляция як майдони дигар илова карда мешавад -private static final long serialVersionUID. Ин майдон дорои идентификатори ягонаи versionи синфи сериализатсияшуда мебошад. Он дар асоси мундариҷаи синф - майдонҳо, тартиби эъломияи онҳо, усулҳо, тартиби эъломияи онҳо ҳисоб карда мешавад. Мутаносибан, бо ҳар гуна тағирот дар синф, ин майдон арзиши худро тағир медиҳад. Вақте ки синф сериализатсия мешавад, ин майдон ба ҷараён навишта мешавад. Дар омади гап, ин шояд ягона ҳолате бошад, ки ба ман маълум аст, вақте ки staticяк майдон сериализатсия мешавад. Ҳангоми бесериализатсия арзиши ин майдон бо дараҷаи синфи мошини виртуалӣ муқоиса карда мешавад. Агар арзишҳо мувофиқат накунанд, истисно ба монанди ин партофта мешавад:
java.io.InvalidClassException: test.ser2.ChildExt;
    local class incompatible: stream classdesc serialVersionUID = 8218484765288926197,
                                   local class serialVersionUID = 1465687698753363969
Бо вуҷуди ин, роҳе вуҷуд дорад, ки агар ин чекро фиреб надиҳад. Ин метавонад муфид бошад, агар маҷмӯи майдонҳои синф ва тартиби онҳо аллакай муайян карда шуда бошад, аммо усулҳои синф метавонанд тағир ёбанд. Дар ин ҳолат, сериализатсия зери хатар нест, аммо механизми стандартӣ имкон намедиҳад, ки маълумот бо истифода аз byte-codeи синфи тағирёфта бесерия карда шавад. Аммо, чунон ки гуфтам, уро фиреб додан мумкин аст. Маҳз, майдонро дар синф ба таври дастӣ муайян кунед private static final long serialVersionUID. Дар асл, арзиши ин соҳа метавонад комилан ҳама чиз бошад. Баъзе одамон бартарӣ медиҳанд, ки онро ба санаи тағир додани code баробар кунанд. Баъзеҳо ҳатто 1 л истифода мебаранд. Барои ба даст овардани арзиши стандартӣ (ки дар дохor он ҳисоб карда мешавад), шумо метавонед утorтаи сериалиро, ки ба SDK дохил карда шудааст, истифода баред. Пас аз он ки ин тавр муайян карда мешавад, арзиши майдон собит карда мешавад, аз ин рӯ ба бесериализатсия ҳамеша иҷозат дода мешавад. Ғайр аз он, дар versionи 5.0, дар ҳуҷҷатҳо тақрибан инҳо пайдо шуданд: тавсия дода мешавад, ки ҳамаи синфҳои сериализатсияшаванда ин майдонро ба таври возеҳ эълон кунанд, зеро ҳисобкунии пешфарз ба ҷузъиёти сохтори синф хеле ҳассос аст, ки вобаста ба татбиқи компилятор метавонад фарқ кунад. ва ҳамин тавр боиси InvalidClassExceptionоқибатҳои ғайричашмдошт мегардад. Беҳтар аст, ки ин соҳа ҳамчун private, зеро он танҳо ба синфе, ки дар он эълон шудааст, дахл дорад. Гарчанде ки тағирдиҳанда дар мушаххасот нишон дода нашудааст. Биёед ҳоло ин ҷиҳатро баррасӣ кунем. Фарз мекунем, ки мо ин сохтори синфӣ дорем:
public class A{
    public int iPublic;
    protected int iProtected;
    int iPackage;
    private int iPrivate;
}

public class B extends A implements Serializable{}
Ба ибораи дигар, мо синфе дорем, ки аз волидайни сериализатсиянашаванда мерос гирифта шудааст. Оё ин синфро сериал кардан мумкин аст ва барои ин чӣ лозим аст? Бо тағирёбандаҳои синфи волидайн чӣ мешавад? Ҷавоб ин аст. Бале, Bшумо метавонед як мисоли синфро силсилавӣ кунед. Барои ин чй лозим? Аммо синф бояд Aконструктори бидуни параметр publicё protected. Сипас, ҳангоми бесериализатсия, ҳамаи тағирёбандаҳои синфӣ Aбо истифода аз ин созанда оғоз карда мешаванд. Тағйирёбандаҳои синф Bбо арзишҳои ҷараёни маълумотҳои силсилавӣ оғоз карда мешаванд. BАз ҷиҳати назариявӣ, дар синф усулҳоеро муайян кардан мумкин аст , ки ман дар аввал дар бораи он гуфта будам - readObject​​ва writeObject, - дар ибтидои онҳо бояд (де-)сериализатсияи тағирёбандаҳои синфӣ Bтавассути in.defaultReadObject/out.defaultWriteObject, ва сипас (де-)сериализатсияи тағирёбандаҳои дастрас иҷро карда шаванд. аз синф A(дар ҳолати мо инҳо мебошанд iPublic, iProtectedва iPackage, агар Bон дар як бастаи бо A). Аммо, ба назари ман, беҳтар аст, ки барои ин силсилаи васеъро истифода баред. Нуктаи навбатӣ, ки ман мехоҳам ба он муроҷиат кунам, ин силсилаизатсияи an objectҳои сершумор мебошад. Фарз мекунем, ки мо сохтори зерини синф дорем:
public class A implements Serializable{
    private C c;
    private B b;
    public void setC(C c) {this.c = c;}
    public void setB(B b) {this.b = b;}
    public C getC() {return c;}
    public B getB() {return b;}
}
public class B implements Serializable{
    private C c;
    public void setC(C c) {this.c = c;}
    public C getC() {return c;}
}
public class C implements Serializable{
    private A a;
    private B b;
    public void setA(A a) {this.a = a;}
    public void setB(B b) {this.b = b;}
    public B getB() {return b;}
    public A getA() {return a;}
}
Сериализатсия ҳамон тавре ки ҳаст.  Қисми 1 - 2Агар шумо як мисоли синфро силсилавӣ кунед, чӣ мешавад A? Он як мисоли синфро кашола мекунад B, ки он дар навбати худ дар баробари мисоле C, ки ба инстансия ишора мекунад A, ҳамонеро, ки ҳамааш бо он оғоз шудааст, кашола мекунад. Доираи бераҳмона ва рекурсияи беохир? Хушбахтона, не. Биёед рамзи санҷиши зеринро бубинем:
// initiaizing
A a = new A();
B b = new B();
C c = new C();
// setting references
a.setB(b);
a.setC(c);
b.setC(c);
c.setA(a);
c.setB(b);
// serializing
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(a);
oos.writeObject(b);
oos.writeObject(c);
oos.flush();
oos.close();
// deserializing
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()));
A a1 = (A)ois.readObject();
B b1 = (B)ois.readObject();
C c1 = (C)ois.readObject();
// testing
System.out.println("a==a1: "+(a==a1));
System.out.println("b==b1: "+(b==b1));
System.out.println("c==c1: "+(c==c1));
System.out.println("a1.getB()==b1: "+(a1.getB()==b1));
System.out.println("a1.getC()==c1: "+(a1.getC()==c1));
System.out.println("b1.getC()==c1: "+(b1.getC()==c1));
System.out.println("c1.getA()==a1: "+(c1.getA()==a1));
System.out.println("c1.getB()==b1: "+(c1.getB()==b1));
Мо чӣ кор карда истодаем? Мо як мисоли синфҳоро эҷод мекунем Aва ба онҳо истинод ба ҳамдигар медиҳем ва сипас ҳар яки онҳоро силсилавӣ мекунем B. CСипас, мо онҳоро баргардонем ва як қатор санҷишҳоро иҷро мекунем. Дар натиҷа чӣ мешавад:
a==a1: false
b==b1: false
c==c1: false
a1.getB()==b1: true
a1.getC()==c1: true
b1.getC()==c1: true
c1.getA()==a1: true
c1.getB()==b1: true
Пас, шумо аз ин санҷиш чӣ омӯхта метавонед? Аввал. Истинодҳои an object пас аз бесериализатсия аз истинодҳои пеш аз он фарқ мекунанд. Ба ибораи дигар, ҳангоми силсиласозӣ/десериализатсия an object нусхабардорӣ карда шуд. Ин усул баъзан барои клон кардани an objectҳо истифода мешавад. Хулосаи дуюм муҳимтар аст. Ҳангоми сериализатсия/десериализатсияи an objectҳои сершумор, ки истинодҳои байнисоҳавӣ доранд, он истинодҳо пас аз десериализатсия эътибор доранд. Ба ибораи дигар, агар пеш аз сериализатсия онҳо ба як an object ишора карда бошанд, пас пас аз сериализатсия онҳо низ ба як an object ишора мекунанд. Боз як санҷиши хурд барои тасдиқи ин:
B b = new B();
C c = new C();
b.setC(c);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(b);
oos.writeObject(c);
oos.writeObject(c);
oos.writeObject(c);
oos.flush();
oos.close();
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()));
B b1 = (B)ois.readObject();
C c1 = (C)ois.readObject();
C c2 = (C)ois.readObject();
C c3 = (C)ois.readObject();
System.out.println("b1.getC()==c1: "+(b1.getC()==c1));
System.out.println("c1==c2: "+(c1==c2));
System.out.println("c1==c3: "+(c1==c3));
Объекти синф Bба an objectи синф ишора дорад C. Ҳангоми сериализатсия, bон дар якҷоягӣ бо як мисоли синф сериализатсия карда мешавад С, ки баъд аз он ҳамон як мисоли c се маротиба сериализатсия карда мешавад. Пас аз сериализатсия чӣ мешавад?
b1.getC()==c1: true
c1==c2: true
c1==c3: true
Тавре ки шумо мебинед, ҳамаи чаҳор an objectи бесерияшуда воқеан як an objectро ифода мекунанд - истинодҳо ба он баробаранд. Маҳз ҳамон тавре ки пеш аз сериализатсия буд. Боз як нуктаи ҷолиб - чӣ мешавад, агар мо дар як вақт амалӣ кунем Externalizableва Serializable? Мисли ин савол - фил ва кит - кӣ киро мағлуб мекунад? ғалаба хоҳад кард Externalizable. Механизми сериализатсия аввал мавҷудияти онро месанҷад ва танҳо баъд мавҷудияти онро месанҷад.Пас, Serializableагар синфи B, ки амалӣ мекунад Serializable, аз синфи А, ки амалӣ мекунад, мерос гирад Externalizable, майдонҳои синфи B серия карда намешаванд. Нуқтаи охирин мерос аст. Ҳангоми мерос аз синфе, ки амалӣ мекунад Serializable, ҳеҷ гуна амали иловагӣ лозим нест. Сериализатсия ба синфи кӯдакон низ паҳн хоҳад шуд. Ҳангоми мерос аз синфе, ки -ро амалӣ мекунад Externalizable, шумо бояд усулҳои readExternal ва writeExternal синфи волидайнро аз байн баред. Дар акси ҳол, майдонҳои синфи кӯдак силсила карда намешаванд. Дар ин ҳолат, шумо бояд ба ёд оред, ки усулҳои волидайнро даъват кунед, вагарна майдонҳои волидайн силсила карда намешаванд. * * * Мо эҳтимол бо тафсилот анҷом додаем. Аммо як масъалае ҳаст, ки мо ба он дахл накардаем, ки хусусияти глобалӣ дорад. Аз ҷумла -

Чаро ба шумо Externalizable лозим аст?

Чаро ба мо умуман сериализатсияи пешрафта лозим аст? Ҷавоб оддӣ аст. Аввалан, он чандирии бештар медиҳад. Дуввум, он метавонад аксар вақт аз ҷиҳати ҳаҷми маълумоти силсилавӣ фоидаи назаррас ба даст орад. Сеюм, як ҷанбаи иҷроиш вуҷуд дорад, ки мо дар бораи он дар поён сӯҳбат хоҳем кард . Чунин ба назар мерасад, ки ҳама чиз бо чандирӣ равшан аст. Дарвоқеъ, мо метавонем равандҳои сериализатсия ва бесериализатсияро тавре ки мехоҳем, назорат кунем, ки ин моро аз ҳама гуна тағирот дар синф мустақил мекунад (чунон ки ман дар боло гуфтам, тағирот дар синф метавонад аз сериализатсия ба таври ҷиддӣ таъсир расонад). Аз ин рӯ, ман мехоҳам дар бораи афзоиши ҳаҷми чанд сухан бигӯям. Фарз мекунем, ки мо синфи зерин дорем:
public class DateAndTime{

  private short year;
  private byte month;
  private byte day;
  private byte hours;
  private byte minutes;
  private byte seconds;

}
Боқимонда аҳамият надорад. Майдонҳо метавонанд аз навъи int сохта шаванд, аммо ин танҳо таъсири мисолро беҳтар мекунад. Гарчанде ки дар асл майдонҳо метавонанд intбо сабабҳои иҷро чоп карда шаванд. Дар ҳар сурат, нукта равшан аст. Синф сана ва вақтро ифода мекунад. Ин барои мо пеш аз ҳама аз нуқтаи назари сериализатсия ҷолиб аст. Шояд осонтарин кор ин нигоҳ доштани тамғаи вақт бошад. Он аз навъи дароз аст, яъне. ҳангоми сериализатсия он 8 byte мегирад. Илова бар ин, ин равиш усулҳои табдил додани ҷузъҳоро ба як арзиш ва бозгашт талаб мекунад, яъне. - талафи ҳосилнокӣ. Бартарии ин равиш санаи комилан девона аст, ки метавонад дар 64 бит мувофиқ бошад. Ин як маржаи бузурги бехатарӣ аст, ки аксар вақт дар воқеият лозим нест. Синфи дар боло овардашуда 2 + 5 * 1 = 7 byte мегирад. Илова бар ин, хароҷот барои синф ва 6 майдон. Оё ягон роҳи фишурдани ин маълумот вуҷуд дорад? Бешубҳа. Сонияҳо ва дақиқаҳо дар ҳудуди 0-59 мебошанд, яъне. Барои муаррифии онҳо ба ҷои 8 6 бит кифоя аст. Соат – 0-23 (5 бит), рӯзҳо – 0-30 (5 бит), моҳҳо – 0-11 (4 бит). Ҳама чиз, ҳама чиз бе назардошти сол - 26 бит. То андозаи int то ҳол 6 бит боқӣ мондааст. Аз ҷиҳати назариявӣ, дар баъзе мавридҳо ин метавонад барои як сол кофӣ бошад. Дар акси ҳол, илова кардани byteи дигар андозаи майдони маълумотро то 14 бит зиёд мекунад, ки диапазони 0-16383-ро медиҳад. Ин дар барномаҳои воқеӣ беш аз кофӣ аст. Дар маҷмӯъ, мо андозаи маълумотро барои нигоҳ доштани маълумоти зарурӣ то 5 byte кам кардем. Агар на то 4. Камбудӣ ҳамон тавре ки дар ҳолати қаблӣ аст - агар шумо санаи бастабандиро нигоҳ доред, пас усулҳои табдилдиҳӣ лозиманд. Аммо ман мехоҳам инро ин тавр иҷро кунам: онро дар майдонҳои алоҳида нигоҳ доред ва онро дар шакли бастабандишуда силсилавӣ кунед. Ин аст, ки дар он ҷо истифодаи он маъно дорад Externalizable:
// data is packed into 5 bytes:
//  3         2         1
// 10987654321098765432109876543210
// hhhhhmmmmmmssssssdddddMMMMyyyyyy yyyyyyyy
public void writeExternal(ObjectOutput out){
    int packed = 0;
    packed += ((int)hours) << 27;
    packed += ((int)minutes) << 21;
    packed += ((int)seconds) << 15;
    packed += ((int)day) << 10;
    packed += ((int)month) << 6;
    packed += (((int)year) >> 8) & 0x3F;
    out.writeInt(packed);
    out.writeByte((byte)year);
}

public void readExternal(ObjectInput in){
    int packed = in.readInt();
    year = in.readByte() & 0xFF;
    year += (packed & 0x3F) << 8;
    month = (packed >> 6) & 0x0F;
    day = (packed >> 10) & 0x1F;
    seconds = (packed >> 15) & 0x3F;
    minutes = (packed >> 21) & 0x3F;
    hours = (packed >> 27);
}
Дар асл, ҳамааш ҳамин аст. Пас аз силсиласозӣ, мо дар як синф, ду майдон (ба ҷои 6) ва 5 byte маълумот мегирем. Ки аллакай ба таври назаррас беҳтар аст. Бастабандии минбаъдаро ба китобхонаҳои махсус гузоштан мумкин аст. Мисоли овардашуда хеле содда аст. Мақсади асосии он нишон додани он аст, ки чӣ гуна метавон сериализатсияи пешрафтаро истифода бурд. Гарчанде ки фоидаи имконпазир дар ҳаҷми маълумоти силсилавӣ аз бартарии асосӣ дур аст, ба андешаи ман. Бартарии асосӣ, ба ғайр аз чандирӣ... (ҳамвор ба қисмати оянда гузаред...) Истинод ба манбаъ: Сериализатсия ҳамчунон
Шарҳҳо
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION