Serializacja Java - zalety i wady, używać czy unikać? [Zamknięte]

20

Serializacja służy do trwałości w Javie. Zachowanie kilku obiektów przy użyciu serializacji może być w porządku. Ale w przypadku dużej liczby obiektów lepsza może być ORM, baza danych itp. Wydaje się, że serializacja jest przydatna tylko w przypadku małych prac. Może się mylę. Więc proszę powiedz mi, jakie są zalety serializacji w porównaniu z metodami nie serializacji? Kiedy należy go używać, a kiedy należy tego unikać?

To pytanie przyszło mi do głowy po przeczytaniu artykułu DZone Is Object Serialization Evil?

A oto linie, które zrodziły moje pytanie:

Jeśli spojrzysz na Javę i jej obiekty sesji, używana jest serializacja czystych obiektów. Zakładając, że sesja aplikacji jest dość krótkotrwała, co oznacza najwyżej kilka godzin, serializacja obiektów jest prosta, dobrze obsługiwana i wbudowana w koncepcję sesji Java. Jednak gdy trwałość danych trwa dłużej, być może dni lub tygodnie, i musisz martwić się nowymi wersjami aplikacji, serializacja szybko staje się zła. Jak każdy dobry programista Java wie, jeśli planujesz serializować obiekt, nawet w sesji, potrzebujesz prawdziwego identyfikatora serializacji (serialVersionUID), a nie tylko 1L i musisz zaimplementować interfejs Serializable. Jednak większość programistów nie zna prawdziwych reguł procesu deserializacji Java. Jeśli Twój obiekt się zmienił, to nie tylko dodawanie prostych pól do obiektu, możliwe jest, że Java nie może poprawnie przekształcić obiektu z postaci szeregowej, nawet jeśli identyfikator serializacji nie zmienił się. Nagle nie możesz odzyskać swoich danych, co jest z natury złe.

Teraz programiści czytający to mogą powiedzieć, że nigdy nie napisaliby kodu, który miałby ten problem. To może być prawda, ale co z biblioteką, której używasz lub innym programistą, który nie jest już zatrudniony w Twojej firmie? Czy możesz zagwarantować, że ten problem nigdy się nie wydarzy? Jedynym sposobem na zagwarantowanie tego jest użycie innej metody serializacji.

drapacz chmur
źródło
Czy mógłbyś rozwinąć nieco temat tego, co konkretnie we wspomnianym artykule spowodowało twoje pytanie?
komar
@gnat - dodał wiersze do pytania.
skrobaczka do nieba
Część o „nie tylko 1L” jest nieprawidłowa.
user207421,

Odpowiedzi:

15

Serializacja jest najczęściej stosowana w dwóch obszarach:

  • prototypowanie trwałości

    praktycznie każdy wykres obiektowy można szybko przekształcić do postaci szeregowej, w przypadku szybkiej weryfikacji koncepcji lub szybkich i brudnych aplikacji może to być szybsze niż skonfigurowanie prawdziwej warstwy ORM lub innego systemu trwałości

  • krótkotrwałe przechowywanie prawie dowolnych obiektów:

    Na przykład serwery aplikacji mają tendencję do utrwalania informacji o sesji przy użyciu serializacji. Ma to tę zaletę, że wartości w sesji mogą być prawie dowolnego typu (o ile jest to możliwe do serializacji).

W przypadku prawie wszystkich innych zastosowań wady, o których wspominasz (i artykuł) są zbyt duże: dokładny format jest trudny do utrzymania w stabilnym stanie, zmiany klas mogą z łatwością sprawić, że twoje serializowane dane będą nieczytelne, odczyt / zapis danych w kodzie innym niż Java jest prawie niemożliwe (lub przynajmniej o wiele trudniejsze niż to konieczne).

JAXB i podobne technologie zapewniają podobne funkcje przy podobnie niskim koszcie, jednocześnie zmniejszając niektóre problemy.

Joachim Sauer
źródło
Nie nazwałbym JAXB „niskim kosztem” - schemat musi zostać napisany.
kevin cline
3
@kevincline: nie potrzebujesz schematu z JAXB, jest on całkowicie opcjonalny (możesz go nawet wygenerować ze swoich klas, jeśli chcesz). Ponadto: jeśli JAXB z jakiegoś powodu nie jest użyteczny, istnieje wiele alternatyw, takich jak XML Beans, które działają równie dobrze.
Joachim Sauer
12

Używam serializacji obiektów, aby umożliwić sekcję zwłok w przypadku nieoczekiwanego błędu w produkcji. Dane wejściowe do obliczeń są serializowane do pliku danych. Jeśli zostanie zgłoszony błąd, prosty program może ponownie załadować dane wejściowe i ponownie uruchomić obliczenia z podłączonym debugerem. Lub groovy shell może być użyty do przeładowania obiektów i zmodyfikowania ich w razie potrzeby.

Używamy również serializacji do przekazywania obiektów Java przez HTTP do usługi internetowej. Znacznie łatwiejsze niż serializowanie do iz tekstu. Wadą jest to, że instalacje klienta i serwera muszą być wdrażane razem, ale nie stanowi to problemu, ponieważ kontrolujemy oba końce.

Kevin Cline
źródło
3
To ciekawy przypadek użycia! Zbyt mały, by wzywać do „bardziej złożonego” systemu, a większość wad nie ma zastosowania!
Joachim Sauer
Napisaliśmy teraz sekcję zwłok, która wykorzystuje POI do zbudowania arkusza kalkulacyjnego z obiektów Java w celu łatwiejszego przeglądania. To pozwoliło nam zaoszczędzić wiele godzin na sprawdzaniu pliku dziennika.
kevin cline
7

Jakie są zalety serializacji w porównaniu z metodami bez serializacji?

Serializacja w języku Java ma kilka zalet:

  • Wbudowany w system : nie musisz polegać na narzędziach, bibliotekach lub konfiguracji innych firm.

  • Stosunkowo prosty do zrozumienia , przynajmniej na początku.

  • Każdy programista to wie (lub powinien). Niezależnie od tego, czy deweloperzy Java zatwierdzają, czy odrzucają, prawdopodobnie znają szeregowanie obiektów Java.

I oczywiście są wady:

  • Obchodzi standardowy przepływ Java. Przydziela pamięć, ale nie wywołuje konstruktora, więc pola przejściowe nie są inicjowane. Pola są inicjowane w kolejności alfabetycznej, a nie w kolejności źródłowej.

  • Nie tak wydajne pod względem przestrzeni, ale też nie straszne. Możesz skompresować wynik.

  • Kruche, chyba że podejmiesz środki ostrożności, gdy zmienisz przedmiot. I nawet wtedy.

Kiedy należy go używać, a kiedy należy tego unikać?

Użyj, gdy :

  • Rozmiar wdrożenia ma znaczenie. Wbudowany w system, więc 0 dodatkowych bajtów.

  • Wszyscy aktorzy będą używać zgodnych wersji.

  • Przechowywanie długoterminowe nie stanowi problemu.

Unikaj, gdy :

  • Żadne z powyższych nie mają zastosowania.
JvR
źródło
3

Serializacja i ORM / baza danych to różne rzeczy, choć niektóre nakładają się na siebie.

Zserializowany obiekt reprezentuje wszystkie informacje potrzebne do „rozmrożenia” utrwalonego obiektu i ponownego wypełnienia jego danych. ORM i baza danych utrwalają dane w bazie danych. Klasa może mieć pola informacji, które nie są przechowywane w bazie danych przez ORM, na przykład pole obliczane.

Dodatkowo serializacja i ORM rozwiązują różne problemy. Serializacja rozwiązuje problem utrwalania wykresu obiektowego w strumieniu (pamięć, system plików itp.). ORM obsługuje mapowanie fragmentów informacji do kolumn bazy danych oraz pobieranie i tworzenie instancji obiektów, a także zapewnia drobiazgi, takie jak wyszukiwanie i leniwe ładowanie.

Użyj ORM, jeśli chcesz utrwalić dane w bazie danych w sytuacjach, gdy masz do czynienia z dużymi ilościami danych lub potrzebujesz raportowania, wyszukiwania / zapytań, magazynowania lub innych rzeczy, w których bazy danych są dobre. Użyj serializacji, jeśli chcesz zapisać reprezentację swojej struktury danych na dysku.

Sam
źródło
0

Serializacja jest rzadko stosowana w praktyce.

Jak już wspomniano, najczęstszym przypadkiem użycia serializacji jest przechowywanie obiektów jako obiektów blob w bazie danych sesji. Działa to dobrze z dwóch powodów: sesje są zazwyczaj krótkotrwałe, a baza danych sesji nie wie, jak mapować dowolne obiekty na model relacyjny.

W przypadku danych, które muszą być przechowywane przez długi czas (np. Koszyk Amazon), najlepszą praktyką jest przechowywanie tych danych w bazie danych.

Mechanizm utrwalania sesji zapewnia, że ​​użytkownik z aktywną sesją zostanie zwrócony na ten sam serwer. Dostęp do bazy danych sesji można uzyskać tylko w przypadku awarii serwera i przekierowania użytkownika na nowy serwer. Nowy serwer wykrywa aktywną sesję, ale nie znajduje jej w pamięci, więc próbuje pobrać ją z bazy danych sesji, aby zapewnić użytkownikowi bezproblemową obsługę.

Z tym podejściem wiążą się dwa problemy:

Po pierwsze, opróżnianie danych sesji do bazy danych sesji jest procesem powolnym. Dane sesji opróżniania zbyt często obniżają wydajność, a większość serwerów jest skonfigurowana do opróżniania co 30 sekund, co minutę lub dłużej. To „pozorne” rozwiązanie przełączania awaryjnego nigdy nie jest w 100% skuteczne.

Po drugie, z mojego doświadczenia wynika, że ​​większość klientów zgadza się, że wyświetla komunikat o błędzie z prośbą o zalogowanie się i spróbuj ponownie w rzadkich przypadkach awarii serwera. W takim przypadku całkowicie wyłączamy bazę danych sesji i cieszymy się wzrostem wydajności.

Innym zastosowaniem serializacji jest zapewnienie krótszych czasów odpowiedzi za pomocą struktur takich jak Flex, które używają serializacji i kompresji grafów obiektowych do interakcji serwer-klient.

Jak zauważyli inni, istnieje szereg kreatywnych i użytecznych powodów, dla których warto zastosować serializację, ale w praktyce są one rzadkie.

Historycznie serializacja jest trudna do prawidłowego wdrożenia i niezawodności, ograniczając jej zastosowanie do niewielkiej liczby przypadków. Większość programistów nigdy nie serializuje obiektów samodzielnie, ale może polegać na frameworkach, które robią to za kulisami.

eric w
źródło
2
„Serializacja jest rzadko stosowana w praktyce”. - Serializacja jest często wywoływana w świecie usług sieciowych REST. Przez większość czasu po prostu mamy do czynienia z ciągami i liczbami całkowitymi lub podobnymi - ale jest to prawdziwa rzecz, a bardziej złożone obiekty wymagają jej świadomości. Stwierdzenie, że jest rzadko używane, ignoruje duży obszar domen, które często go używają.
0

Krótka odpowiedź na „kiedy używać serializacji Java” i „kiedy unikać serializacji Java”

Użyj serializacji Java, jeśli

  • niewiele kodowania powinno być konieczne
  • nie ma znaczenia, że ​​dane binarne nie są czytelne dla człowieka
  • wyszukiwanie w danych szeregowanych nie jest konieczne (zapytanie podobne do bazy danych nie jest możliwe)
  • zarówno
    • zserializowana struktura danych nie ulega zmianie lub
    • nie ma znaczenia, czy przechowywane zserializowane dane nie są już czytelne po „zmianie struktury danych” (tj. dane sesji w aplikacji internetowej)

We wszystkich innych sytuacjach „serializacja binarna Java” jest zła

Alternatywy

  • serializacja XML
  • baza danych nosql
  • relacyjna baza danych z ORM
k3b
źródło