Interfejsy znaczników i głębokie kopie - 1

"Cześć, Amigo!"

"Cześć, Bilaabo!"

„Dzisiaj opowiem o interfejsach znaczników ”.

„Interfejsy znaczników to interfejsy bez metod. Kiedy klasa implementuje taki interfejs, mówimy, że jest przez niego oznaczona”.

„Przykłady tych interfejsów to: Cloneable, Serializable, Remote ”.

„ Interfejs Serializable służy do oznaczania klas, które obsługują serializację, wskazując, że instancje tych klas mogą być automatycznie serializowane i deserializowane”.

„ Interfejs zdalny służy do identyfikowania obiektów obsługujących zdalne wykonywanie, tj. metod, które można wywołać z innej wirtualnej maszyny Java i/lub innego komputera”.

„ Interfejs Cloneable służy do oznaczania klas obsługujących klonowanie”.

„Och, jeśli chodzi o klonowanie lub kopiowanie”.

„Istnieją dwa rodzaje kopiowania: płytkie i głębokie”.

Płytkie kopiowanie to tworzenie kopii obiektu bez tworzenia duplikatów żadnego z obiektów, do których się odwołuje”.

Głębokie kopiowanie polega na powielaniu obiektu, w tym obiektów, do których się odwołuje, oraz obiektów, do których te obiekty się odwołują itp.”

„Istnieje naprawdę dobry sposób na niezawodne stworzenie głębokiego klonu”.

„Ta metoda działa nawet wtedy, gdy programiści zapomnieli oznaczyć klasę jako Cloneable. „Jedynym wymaganiem jest to, aby obiekty mogły być serializowane”.

„Oto jak to zrobić:”

1) Utwórz bufor (tablicę bajtów) w pamięci.

2) Serializuj obiekt i podobiekty w buforze.

3) Deserializuj hierarchię obiektów zapisaną w buforze.

Kod
BigObject objectOriginal = new BigObject();

ByteArrayOutputStream writeBuffer = new ByteArrayOutputStream();
ObjectOutputStream outputStream = new ObjectOutputStream(writeBuffer);
outputStream.writeObject(objectOriginal);
outputStream.close();

byte[] buffer = writeBuffer.toByteArray();
ByteArrayInputStream readBuffer = new ByteArrayInputStream(buffer);
ObjectInputStream inputStream = new ObjectInputStream(readBuffer);
BigObject objectCopy = (BigObject)inputStream.readObject();

„W pierwszym wierszu tworzymy obiekt objectOriginal , który sklonujemy. Obiekt i wszystkie jego podobiekty muszą obsługiwać serializację”.

„W trzecim wierszu tworzymy ByteArrayOutputStream , który będzie się dynamicznie rozwijał w miarę dodawania nowych danych (jak ArrayList).”

„W linii 4 tworzymy obiekt ObjectOutputStream , który jest używany do serializacji”.

„W wierszu 5 serializujemy objectOriginal do tablicy bajtów za pomocą outputStream i zapisujemy go w writeBuffer ”.

„W linii 8 konwertujemy writeBuffer na zwykłą tablicę bajtów. Później „odczytamy” nasz nowy obiekt z tej tablicy.”

„W wierszu 9 przekształcamy bufor w obiekt ByteArrayInputStream , aby odczytywać go jak strumień wejściowy”.

„W wierszu 10 przekazujemy readBuffer do konstruktora ObjectInputStream , aby odczytać (deserializować) obiekt”.

„W linii 11 czytamy nasz obiekt i konwertujemy go na obiekt BigObject ”.

"Co myślisz?"

"To jest piękne."

„A tak przy okazji, gdy kod jest podświetlony różnymi kolorami, jest znacznie łatwiejszy do zrozumienia”.