Jaka jest różnica między Serializable
i Externalizable
w Javie?
Jaka jest różnica między Serializable
i Externalizable
w Javie?
Aby dodać do innych odpowiedzi, implementując java.io.Serializable
, otrzymujesz możliwość „automatycznej” serializacji obiektów klasy. Nie trzeba implementować żadnej innej logiki, po prostu będzie działać. Środowisko wykonawcze Java użyje refleksji, aby dowiedzieć się, jak organizować i rozmontowywać obiekty.
We wcześniejszej wersji Javy odbicie było bardzo powolne, dlatego serializowanie dużych wykresów obiektowych (np. W aplikacjach RMI klient-serwer) stanowiło trochę problem z wydajnością. Aby poradzić sobie z tą sytuacją, java.io.Externalizable
zapewniono interfejs, który jest podobny, java.io.Serializable
ale z niestandardowymi mechanizmami do wykonywania funkcji rozróżniania i rozróżniania (musisz zaimplementować readExternal
i writeExternal
metody w swojej klasie). Dzięki temu można obejść wąskie gardło związane z wydajnością odbicia.
W najnowszych wersjach Javy (z pewnością od wersji 1.3) wydajność odbicia jest znacznie lepsza niż kiedyś, więc jest to o wiele mniejszy problem. Podejrzewam, że trudno byłoby ci uzyskać znaczącą korzyść Externalizable
z nowoczesnej maszyny JVM.
Ponadto, wbudowany mechanizm serializacji Java nie jest jedynym, można uzyskać zamienniki innych firm, takie jak JBoss Serialization, który jest znacznie szybszy i zastępuje domyślnie.
Dużym minusem Externalizable
jest to, że musisz sam utrzymywać tę logikę - jeśli dodajesz, usuwasz lub zmieniasz pole w swojej klasie, musisz zmienić metody writeExternal
/ readExternal
, aby to uwzględnić.
Podsumowując, Externalizable
jest reliktem Java 1.1 dni. Naprawdę nie ma już takiej potrzeby.
Externalizable
pomaga wiele .Externalizable
bardziej mi odpowiada, ponieważ nie chcę wyprowadzać tablic z pustymi spacjami lub obiektami zastępczymi, a także z jawnym interfejsem, w którym można obsłużyć dziedziczenie, co oznacza, że mój zsynchronizowany sub -klasa może łatwo dodać blokowanie wokół połączenia dowriteExternal()
. Tak, Eksternalizowalny jest nadal bardzo istotny, z pewnością w przypadku dużych lub złożonych obiektów.Serializacja zapewnia domyślną funkcjonalność do przechowywania, a następnie odtworzenia obiektu. Używa pełnego formatu, aby zdefiniować cały wykres obiektów, które mają być przechowywane, np. Załóżmy, że masz linkedList i kodujesz jak poniżej, wówczas domyślna serializacja wykryje wszystkie połączone obiekty i serializuje. W domyślnej serializacji obiekt jest zbudowany w całości z przechowywanych bitów, bez wywołań konstruktora.
Ale jeśli chcesz ograniczyć serializację lub nie chcesz, aby jakaś część twojego obiektu była serializowana, użyj opcji Zewnętrzna. Interfejs zewnętrzny umożliwia rozszerzenie interfejsu szeregowego i dodaje dwie metody: writeExternal () i readExternal (). Są one automatycznie wywoływane podczas serializacji lub deserializacji. Pracując z Externalizable powinniśmy pamiętać, że domyślny konstruktor powinien być publiczny, w przeciwnym razie kod zgłosi wyjątek. Postępuj zgodnie z poniższym kodem:
Jeśli skomentujesz domyślny konstruktor, kod wygeneruje wyjątek poniżej:
Możemy zauważyć, że ponieważ hasło jest poufną informacją, więc nie serializuję go metodą writeExternal (ObjectOutput oo) i nie ustawiam jego wartości w readExternal (ObjectInput oi). To elastyczność zapewniana przez firmę zewnętrzną.
Dane wyjściowe powyższego kodu są następujące:
Możemy to zaobserwować, ponieważ nie ustawiamy wartości hasła, więc jest ono puste.
To samo można również osiągnąć, deklarując pole hasła jako przejściowe.
Mam nadzieję, że to pomoże. Przepraszam, jeśli popełniłem jakieś błędy. Dzięki.
źródło
Kluczowe różnice między
Serializable
iExternalizable
Serializable
jest interfejsem znaczników bez żadnych metod.Externalizable
interfejs zawiera dwie metody:writeExternal()
ireadExternal()
.Serializable
interfejs. Zdefiniowany przez programistę proces szeregowania zostanie uruchomiony dla klas implementującychExternalizable
interfejs.Externalizable
interfejsem. Możesz obsługiwać różne wersje swojego obiektu. Jeśli wdrożyszExternalizable
, Twoim obowiązkiem jest serializacjasuper
klasySerializable
wykorzystuje odbicie do konstruowania obiektu i nie wymaga konstruktora arg. AleExternalizable
wymaga publicznego konstruktora bez argumentów.Patrz blog o
Hitesh Garg
więcej szczegółów.źródło
Serializacja wykorzystuje pewne domyślne zachowania do przechowywania, a następnie odtworzenia obiektu. Możesz określić, w jakiej kolejności lub w jaki sposób obsługiwać odwołania i złożone struktury danych, ale ostatecznie sprowadza się to do użycia domyślnego zachowania dla każdego pierwotnego pola danych.
Eksternalizacja jest stosowana w rzadkich przypadkach, gdy naprawdę chcesz przechowywać i odbudowywać obiekt w zupełnie inny sposób i bez użycia domyślnych mechanizmów serializacji dla pól danych. Na przykład wyobraź sobie, że masz swój własny unikalny schemat kodowania i kompresji.
źródło
Serializacja obiektów wykorzystuje interfejsy szeregowalne i możliwe do uzewnętrznienia. Obiekt Java jest możliwy do serializacji. jeśli klasa lub którakolwiek z jej nadklas implementuje interfejs java.io.Serializable lub jego podinterface java.io.Externalizable. Większość klas Java można serializować .
NotSerializableException
:packageName.ClassName
«Aby uczestniczyć w obiektu klasy w procesie serializacji, klasa musi implementować interfejs szeregowy lub zewnętrzny.Interfejs szeregowy
Serializacja obiektów tworzy strumień z informacjami o klasach Java dla zapisywanych obiektów. W przypadku obiektów możliwych do serializacji przechowywane są wystarczające informacje, aby przywrócić te obiekty, nawet jeśli istnieje inna (ale zgodna) wersja implementacji klasy. Interfejs szeregowalny jest zdefiniowany w celu identyfikacji klas, które implementują protokół szeregowalny:
InvalidClassException
«W procesie deserializacji, jeśli wartość lokalnej klasy serialVersionUID jest różna od odpowiedniej klasy nadawcy. wynik jest w konflikcie jakojava.io.InvalidClassException: com.github.objects.User; local class incompatible: stream classdesc serialVersionUID = 5081877, local class serialVersionUID = 50818771
Interfejs zewnętrzny
W przypadku obiektów podlegających eksternalizacji tylko tożsamość klasy obiektu jest zapisywana przez kontener; klasa musi zapisać i przywrócić zawartość. Interfejs zewnętrzny można zdefiniować w następujący sposób:
OptionalDataException
«Pola muszą być w takim samym porządku i rodzaju, jak je zapisaliśmy. Jeśli występuje niezgodność typu ze strumienia, generuje wyjątek OptionalDataException.Pola instancji klasy, które napisały (ujawniły), aby
ObjectOutput
zostały serializowane.Przykład « implementuje Serializable
Przykład « implementuje eksternalizowalne
Przykład
@widzieć
źródło
Interfejs zewnętrzny nie został faktycznie udostępniony w celu optymalizacji wydajności procesu serializacji! ale aby zapewnić środki do implementacji własnego przetwarzania niestandardowego i zaoferować pełną kontrolę nad formatem i zawartością strumienia dla obiektu i jego super typów!
Przykładem może być implementacja zdalnego AMF (ActionScript Message Format) do przesyłania natywnych obiektów skryptów akcji przez sieć.
źródło
https://docs.oracle.com/javase/8/docs/platform/serialization/spec/serialTOC.html
Domyślna serializacja jest nieco szczegółowa i zakłada najszerszy możliwy scenariusz użycia serializowanego obiektu, a zatem domyślny format (Serializable) adnotuje wynikowy strumień informacją o klasie obiektu serializowanego.
Eksternalizacja daje producentowi strumienia obiektowego pełną kontrolę nad dokładnymi metadanymi klasy (jeśli istnieje) poza minimalną wymaganą identyfikacją klasy (np. Jej nazwą). Jest to wyraźnie pożądane w niektórych sytuacjach, takich jak środowiska zamknięte, w których dopasowuje się producenta strumienia obiektowego i jego konsumenta (który weryfikuje obiekt ze strumienia), a dodatkowe metadane dotyczące klasy nie mają żadnego celu i obniżają wydajność.
Dodatkowo (jak wskazał Uri) eksternalizacja zapewnia również pełną kontrolę nad kodowaniem danych w strumieniu odpowiadającym typom Java. Na przykład (wymyślony) możesz zapisać logiczną wartość logiczną true jako „Y” i false jako „N”. Eksternalizacja pozwala to zrobić.
źródło
Rozważając opcje poprawy wydajności, nie zapomnij o niestandardowej serializacji. Możesz pozwolić Javie robić to, co robi dobrze lub przynajmniej wystarczająco dobrze, za darmo i zapewniać niestandardową obsługę tego, co robi źle. Zazwyczaj jest to o wiele mniej kodu niż pełne wsparcie zewnętrzne.
źródło
Istnieje tak wiele różnic między serializowalnym a zewnętrznym, ale gdy porównamy różnicę między niestandardowym szeregowalnym (przesłoniętym writeObject () i readObject ()) a zewnętrznym, to okazuje się, że niestandardowa implementacja jest ściśle powiązana z klasą ObjectOutputStream, gdzie tak jak w przypadku zewnętrznym, my sami zapewnić implementację ObjectOutput, która może być klasą ObjectOutputStream lub inną, np. org.apache.mina.filter.codec.serialization.ObjectSerializationOutputStream
W przypadku interfejsu zewnętrznego
Dodałem przykładowy kod, aby lepiej wyjaśnić. proszę sprawdzić / wyewidencjonować przypadek obiektowy Zewnętrznego. Nie są one związane bezpośrednio z żadną implementacją.
Gdzie jako Outstream / Instream są ściśle związane z klasami. Możemy rozszerzyć ObjectOutputStream / ObjectInputStream, ale będzie to nieco trudne w użyciu.
źródło
Zasadniczo
Serializable
jest interfejsem znaczników, który sugeruje, że klasa jest bezpieczna do serializacji, a JVM określa jej sposób serializacji.Externalizable
zawiera 2 metodyreadExternal
orazwriteExternal
.Externalizable
pozwala implementatorowi decydować o sposobie serializacji obiektu, przy czymSerializable
serializuje obiekty w sposób domyślny.źródło
Niektóre różnice:
W przypadku serializacji nie ma potrzeby domyślnego konstruktora tej klasy, ponieważ Object, ponieważ JVM konstruuje to samo za pomocą Reflection API. W przypadku eksternalizacji wymagany jest konstruktor bez argumentu, ponieważ kontrola jest w rękach programmar, a następnie przypisuje zdezrializowane dane do obiektu za pomocą ustawiaczy.
W serializacji, jeśli użytkownik chce pominąć pewne właściwości, które mają być serializowane, to musi zaznaczyć te właściwości jako przejściowe, i odwrotnie nie jest wymagane dla eksternalizacji.
Jeśli dla dowolnej klasy oczekiwane jest wsparcie zgodności z poprzednimi wersjami, zaleca się skorzystanie z opcji Zewnętrzne. Serializacja obsługuje domyślny obiekt defaultObject, a jeśli struktura obiektu zostanie uszkodzona, spowoduje to problem podczas deserializacji.
źródło