Serializacja w Javie: readObject () vs. readResolve()

Książka Effective Java i inne źródła dostarczają całkiem dobrego wyjaśnienia jak i kiedy używać metody readObject () podczas pracy z serializowalnymi klasami Javy. Z drugiej strony metoda readResolve() pozostaje nieco tajemnicą. Zasadniczo wszystkie dokumenty znalazłem albo wspomnieć tylko jeden z dwóch lub wymienić oba tylko indywidualnie.

Pytania pozostające bez odpowiedzi to:

  • Jaka jest różnica między tymi dwoma metodami?
  • Kiedy należy jaką metodę wdrożyć?
  • jak powinno się używać funkcji readResolve (), zwłaszcza jeśli chodzi o zwracanie co?

Mam nadzieję, że możesz rzucić trochę światła na tę sprawę.

Author: Aniket Thakur, 2009-07-23

9 answers

readResolve służy do zastąpienia obiektu odczytywanego ze strumienia. Jedynym zastosowaniem, jakie kiedykolwiek widziałem, jest wymuszanie singletonów; gdy obiekt jest odczytywany, zastąp go instancją singleton. Zapewnia to, że nikt nie może utworzyć innej instancji przez serializowanie i deserializowanie singleton.

 110
Author: Michael Myers,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-22 21:31:23

Metoda readResolve jest wywoływana, gdy ObjectInputStream odczytuje obiekt ze strumienia i przygotowuje się do zwrócenia go do wywołującego. ObjectInputStream sprawdza, czy klasa obiektu definiuje metodę readResolve. Jeżeli metoda jest zdefiniowana, to metoda readResolve jest wywołana, aby obiekt w strumieniu mógł wyznaczyć obiekt, który ma być zwrócony. Zwracany obiekt powinien być typu zgodnego ze wszystkimi zastosowaniami. Jeśli nie jest kompatybilny, ClassCastException zostanie wyrzucony, gdy zostanie wykryta niedopasowanie typu.

 33
Author: AZ_,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-20 02:41:52

readResolve jest wywoływane po zwróceniu readObject (odwrotnie writeReplace jest wywoływane przed writeObject i prawdopodobnie na innym obiekcie). Obiekt, który zwraca metoda zastępuje obiekt this zwrócony użytkownikowi ObjectInputStream.readObject i wszelkie dalsze odwołania wstecz do obiektu w strumieniu. Jest on używany głównie dla serwerów proxy (zobacz Effective Java, 2nd Ed, IIRC).

 24
Author: Tom Hawtin - tackline,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-07 07:16:17

ReadResolve można zastosować do zmiany danych serializowanych metodą readObject. Na przykład XSTREAM API używa tej funkcji do inicjalizacji niektórych atrybutów, które nie były w XML do deserializacji.

Http://x-stream.github.io/faq.html#Serialization

 9
Author: endless,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-01 12:01:09

ReadResolve jest przeznaczony do sytuacji, gdy konieczne może być zwrócenie istniejącego obiektu, np. dlatego, że sprawdzasz duplikaty danych wejściowych, które powinny być scalone, lub (np. w systemach rozproszonych, które ostatecznie są spójne), ponieważ jest to aktualizacja, która może nadejść, zanim poznasz starsze wersje.

 5
Author: user833771,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-27 19:47:07

ReadResolve () zapewni kontrakt Singletona podczas serializacji.
Proszę. refer

 3
Author: Kanagavelu Sugumar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-07 06:05:18

Gdy serializacja jest używana do konwersji obiektu tak, aby mógł zostać zapisany w pliku, możemy wywołać metodę readResolve (). Metoda jest prywatna i jest przechowywana w tej samej klasie, której obiekt jest pobierany podczas deserializacji. Zapewnia, że po deserializacji zwracany obiekt będzie taki sam, jak został serializowany. Czyli instanceSer.hashCode() == instanceDeSer.hashCode()

Metoda ReadResolve() nie jest metodą statyczną. Po wywołaniu in.readObject() podczas deserializacji upewnia się tylko, że zwracany obiekt jest taki sam jak ten, który był serializowany jak poniżej, podczas gdy out.writeObject(instanceSer)
..
    ObjectOutput out = new ObjectOutputStream(new FileOutputStream("file1.ser"));
    out.writeObject(instanceSer);
    out.close();

W ten sposób pomaga również w implementacji singleton design pattern , ponieważ za każdym razem zwracana jest ta sama instancja.

public static ABCSingleton getInstance(){
    return ABCSingleton.instance; //instance is static 
}
 1
Author: hi.nitish,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-18 19:35:37

ReadObject() jest istniejącą metodą w klasie ObjectInputStream .podczas odczytu obiektu w czasie deserializacji metoda readObject sprawdza wewnętrznie, czy obiekt klasy, który jest deserializowany przy pomocy metody readResolve, czy też nie, Jeżeli istnieje metoda readResolve, to wywoła metodę readResolve i zwróci tę samą instancję.

Tak więc intensywne pisanie metody readResolve jest dobrą praktyką, aby osiągnąć czysty singleton wzór projektowy, gdzie nikt nie może uzyskać innego instancja przez serializowanie/deserializowanie.

 1
Author: arjun kumar mehta,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-15 13:19:15

Metoda readResolve

Dla klas Serializowalnych i zewnętrznych metoda readResolve pozwala klasie zastąpić / rozwiązać obiekt odczytany ze strumienia, zanim zostanie zwrócony do wywołującego. Implementując metodę readResolve, klasa może bezpośrednio kontrolować typy i instancje własnych instancji, które są deserializowane. Metoda jest zdefiniowana w następujący sposób:

any-ACCESS-MODIFIER Object readResolve() rzuty ObjectStreamException;

Metoda readResolve jest wywoływana, gdy ObjectInputStream odczytuje obiekt ze strumienia i przygotowuje się do zwrócenia go do wywołującego. ObjectInputStream sprawdza, czy klasa obiektu definiuje metodę readResolve. Jeżeli metoda jest zdefiniowana, metoda readResolve jest wywołana, aby obiekt w strumieniu mógł wyznaczyć obiekt, który ma być zwrócony. Zwracany obiekt powinien być typu zgodnego ze wszystkimi zastosowania. Jeśli nie jest zgodna, ClassCastException zostanie rzucona, gdy zostanie wykryta niezgodność typu.

Na przykład można utworzyć klasę Symbol, dla której w maszynie wirtualnej istniała tylko jedna instancja każdego wiązania symboli. Metoda readResolve zostałaby zaimplementowana w celu określenia, czy ten symbol był już zdefiniowany i zastąpienia istniejącego wcześniej równoważnego obiektu symbolu, aby utrzymać ograniczenie tożsamości. W ten sposób unikalność Obiekty symboli mogą być utrzymywane w całej serializacji.

 0
Author: Ankush soni,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-28 04:15:18