Programim dhe zhvillim, javascript, python, php, html

Trajtimi i deserializimit të vlerave enum që nuk ekzistojnë më

Unë kam një enum JJJ që ka 3 vlera: A, B dhe C. Në versionet e mëparshme të programit tim kishte një vlerë shtesë: D. Do të doja të isha në gjendje të lexoja në objektet e serializuara të krijuara nga versionet e mëparshme të program, por bëhet një përjashtim kur ndeshet me një variabël të tipit JJJ me vlerë 'D' në objektin e serializuar. Në mënyrë optimale, do të doja të jem në gjendje të përgjoj procesin e deserializimit dhe t'i them që thjesht të vendosë D-të në C-të kur i ndesh ato.

Sipas http://docs.oracle.com/javase/6/docs/platform/serialization/spec/serial-arch.html (Serializimi i konstanteve të Enumit), nuk duket se ka një mënyrë të thjeshtë për ta bërë këtë... Unë e di se një qasja do të ishte të anashkaloni readObject në klasat që përmbajnë variabla anëtare të tipit JJJ, por kjo do të ishte e vështirë dhe e dhimbshme për shkak të madhësisë dhe shtrirjes së programit (dhjetëra klasa të serializueshme kanë vars anëtarë të tipit JJJ dhe readObject mbizotërues për të trajtuar Fusha JJJ do të thotë që do të më duhej të trajtoja manualisht të gjitha fushat e tjera gjithashtu).

Unë jam përpjekur gjithashtu ta zgjidh këtë duke rrotulluar nënklasën time të ObjectInputStream, por për fat të keq, bitet e deserializimit të numrit që duhet të marr dhe të anashkaloj për ta zgjidhur këtë janë të gjitha private ose private të paketave...

Ndonjë sugjerim?

05.01.2012

  • Ky është një shembull se pse serializimi nuk është i përshtatshëm për ruajtjen afatgjatë të të dhënave: skedarët e serializuar janë të lidhur ngushtë me kodin tuaj burimor. Përdorni një format standard, të mirë-dokumentuar dhe të shtrirë për ruajtjen afatgjatë të të dhënave në vend të serializimit Java. 05.01.2012
  • A mund të rishtoni D dhe të paktën ta shënoni si të vjetëruar, për kohën e nevojshme për një migrim? Apo do të thyejë kodin tjetër? 05.01.2012
  • @Lukas - Unë do të doja të mbajë D jashtë enum; pjesë të tjera të programit përsëriten mbi vlerat e këtij enum për qëllime të ndryshme dhe do të kishin nevojë për rregullim për të mbështetur vlerat e padëshiruara të trashëguara. 05.01.2012
  • Të serializohet në një format më të mirë? Mënjanë shakatë, nuk mund të përdorni enumin e vjetër dhe thjesht t'i konvertoni të gjitha D-të në C-të pasi të ngarkoni? 05.01.2012
  • @Jesper - Ndërsa serializimi Java ka disa të meta kur përdoret për këtë qëllim, ai gjithashtu ofron shumë përfitime të tilla si vendosja e më pak barrë mbi programuesit për të serializuar të dhënat dhe mospasja e aq shumë kodeve boilerplate për të bërë gjëra të tilla si serializimi rutinë i objekteve. Megjithëse ndoshta në të ardhmen do të jemi në gjendje të migrojmë në një kornizë më fleksibël... 05.01.2012
  • @BonusLord: JAXB mund të jetë një opsion i mirë për të ardhmen. Ai gjithashtu nuk shton shumë kode boilerplate 05.01.2012

Përgjigjet:


1

Unë në fakt nuk e kam provuar këtë, por ndoshta mund të funksionojë:

  1. Krijo një klasë të re "oldClass" me të njëjtat fusha si ajo e vjetra.

  2. Zgjero ObjectInputStream në mënyrën ky postim përshkruan në mënyrë që ju të deserializoni në një shembull të "oldClass".

  3. Në atë "oldClass" që keni krijuar, zbatoni "readResolve()", në mënyrë që të ktheni një shembull të versionit të ri të klasës tuaj, duke ndryshuar fushat që mungojnë sipas dëshirës tuaj.

05.01.2012
  • Fatkeqësisht, nuk mund të zbatoni 'readResolve()' në një enum (epo ju mundeni por nuk do të thirret~) 05.01.2012

  • 2

    FYI, për çdo shpirt tjetër të varfër atje që përpiqet të trajtojë këtë rast, kjo është zgjidhja që përfundova duke zbatuar:

    Kam krijuar një ndërfaqe të veçantë për enums që duket si kjo:

    public interface SerialCompatEnum {
        public String convertOldValue(String oldValue);
    }
    

    Më pas shkrova një klasë që merr si hyrje një rrymë bajtë të objektit java të serializuar të papërpunuar, e përpunon atë dhe shkruan një version të modifikuar të rrjedhës së bajtit në një rrjedhë dalëse arbitrare. Logjika e përpunimit mbledh çdo rast enum në rrjedhën e serializuar të bajtit dhe përdor metodën convertOldValue për të zëvendësuar konstantën e enumit në rrjedhë me një varg të përditësuar që ekziston në të vërtetë në bazën aktuale të kodit. Ne e drejtojmë të gjithë objektin tonë të serializuar së pari përmes këtij procesori për të parandaluar dështimet totale të shkaktuara nga mungesa e konstantave të numrit.

    Fatkeqësisht, jo një zgjidhje shumë e pastër apo e lehtë. :/

    22.10.2014
  • Ju lutemi ndonjë shembull të veçantë kodi? :) Kohët e fundit po mundohesha me marrjen e këtyre transmetimeve të bajteve nga javax.ws.rs.core.Response dhe përpunimin e tij përpara se të lexoja entitetin, por patjetër që më mungonte diçka... më në fund zbatova versionin alternativ të API-së për të shmangur gjithë dhimbjen :) 22.01.2021
  • Klasa që kam shkruar që trajton modifikimin aktual të rrjedhës së bajtit është një rrëmujë prej ~ 1500 linjash që në thelb është një zbatim i plotë i një analizuesi të bazuar në transmetim për gramatikën / formatin e objekteve të serializuara Java. Nuk është vërtet i lëvizshëm në formën e tij aktuale, por mund të përpiqem ta ripunoj në një bibliotekë të duhur një ditë. 01.03.2021
  • Materiale të reja

    Masterclass Coroutines: Kapitulli-3: Anulimi i korutinave dhe trajtimi i përjashtimeve.
    Mirë se vini në udhëzuesin gjithëpërfshirës mbi Kotlin Coroutines! Në këtë seri artikujsh, unë do t'ju çoj në një udhëtim magjepsës, duke filluar nga bazat dhe gradualisht duke u thelluar në..

    Faketojeni derisa ta arrini me të dhënat false
    A e gjeni ndonjëherë veten duke ndërtuar një aplikacion të ri dhe keni nevojë për të dhëna testimi që duken dhe duken më realiste ose një grup i madh të dhënash për performancën e ngarkesës...

    Si të përdorni kërkesën API në Python
    Kërkesë API në GitHub për të marrë depot e përdoruesve duke përdorur Python. Në këtë artikull, unë shpjegoj procesin hap pas hapi për të trajtuar një kërkesë API për të marrë të dhëna nga..

    Një udhëzues hap pas hapi për të zotëruar React
    Në këtë artikull, do të mësoni se si të krijoni aplikacionin React, do të mësoni se si funksionon React dhe konceptet thelbësore që duhet të dini për të ndërtuar aplikacione React. Learning..

    AI dhe Psikologjia — Pjesa 2
    Në pjesën 2 të serisë sonë të AI dhe Psikologji ne diskutojmë se si makineritë mbledhin dhe përpunojnë të dhëna për të mësuar emocione dhe ndjenja të ndryshme në mendjen e njeriut, duke ndihmuar..

    Esencialet e punës ditore të kodit tim VS
    Shtesat e mia të preferuara - Git Graph 💹 Kjo shtesë është vërtet e mahnitshme, e përdor përpara se të filloj të punoj për të kontrolluar dy herë ndryshimet dhe degët më të fundit, mund të..

    Pse Python? Zbulimi i fuqisë së gjithanshme të një gjiganti programues
    Në peizazhin gjithnjë në zhvillim të gjuhëve të programimit, Python është shfaqur si një forcë dominuese. Rritja e tij meteorike nuk është rastësi. Joshja e Python qëndron në thjeshtësinë,..