Java 17 Recipes


Download 3.2 Mb.
Pdf ko'rish
bet152/245
Sana02.06.2024
Hajmi3.2 Mb.
#1839910
1   ...   148   149   150   151   152   153   154   155   ...   245
Bog'liq
Java 17 Recipes

 How It Works
Java supports serialization, which is the capability of taking an object and creating a 
byte representation that can restore the object later. Using an internal serialization 
mechanism, most of the setup to serialize objects is taken care of. Java transforms 
the properties of an object into a byte stream, which can then be saved to a file or 
transmitted over the wire.
Note The original Java Serialization framework uses reflection to serialize the 
objects, so it might be an issue if serializing/deserializing heavily. There are many 
open source frameworks. Which is best depends on your needs (speed vs. size vs. 
ease of use). See 
https://github.com/eishay/jvm- serializers/wiki/
.
For a class to be serializable, it needs to implement the Serializable interface, 
which is a marker interface. It doesn’t have any methods but instead tells the 
serialization mechanism that allows your class to be serialized. While not evident 
ChApTer 8 InpuT And OuTpuT


299
from the onset, serialization exposes all the internal workings of your class (including 
protected and private members), so if you want to keep secret the authorization code 
for a nuclear launch, you might want to make any class that contains such information 
nonserializable.
It is also necessary that all properties (e.g., members, variables, or fields) of the class 
are serializable (and/or transient, which we get to in a minute). All primitives—int, long, 
double, and float (plus their wrapper classes)—and the String class are serializable by 
design. Other Java classes are serializable on a case-by-case basis. For example, you can’t 
serialize any Swing components (like JButton or JSpinner), and you can’t serialize File 
objects, but you can serialize the Color class (awt.color, to be more precise).
As a design principle, you don’t want to serialize your main classes, but instead, 
you want to create classes containing only the properties you want to serialize. It saves 
a lot of headaches in debugging because serialization becomes very pervasive. If you 
mark a major class as serializable (implements Serializable), and this class contains 
many other properties, you need to declare those classes as serializable as well. If your 
Java class inherits from another class, the parent class should also be serializable. If the 
parent class is not serializable, the parent’s properties are not serialized.
If you want to mark a property as nonserializable, you may mark it as transient
Transient properties tell the Java compiler that you are not interested in saving/loading 
the property value, so it is ignored. Some properties are good candidates for being 
transient, like cached calculations or a date formatter that you always instantiate to the 
same value.
By virtue of the Serialization framework, static properties are not serializable; neither 
are static classes. The reason is that a static class cannot be instantiated, although a 
public static inner class can be instantiated. Therefore, if you save and then load the 
static class at the same time, you have loaded another copy of the static class, throwing 
the JVM for a loop.
The Java serialization mechanism works behind the scenes to convert and traverse 
every object within the class that is marked as Serializable. If an application contains 
objects within objects and even perhaps contains cross-referenced objects, the 
Serialization framework resolves those objects and stores only one copy of any object. 
Each property is translated to a byte[] representation. The format of the byte array 
includes the actual class name (for example, com.somewhere.over.the.rainbow.
preferences.UserPreferences), followed by the encoding of the properties (which in 
turn may encode another object class, with its properties, etc., etc., ad infinitum).
ChApTer 8 InpuT And OuTpuT


300
For the curious, if you look at the file generated (even in a text editor), you can see 
the class name as almost the first part of the file.
Note Serialization is very brittle. By default, the Serialization framework 
generates a Stream Unique Identifier (SUID) that captures information about what 
fields are presented in the class, what kind they are (public/protected), and what is 
transient, among other things. even a perceived slight modification of the class (for 
example, changing an int to a long property) generates a new SuId. A class that 
has been saved with a prior SuId cannot be deserialized on the new SuId. This is 
done to protect the serialization/deserialization mechanism while also protecting 
the designers.
You can tell the Java class to use a specific SuId. This allows you to serialize 
classes, modify them, and then deserialize the original classes while implementing 
some backward compatibility. The danger you run into is that the deserialization 
must be backward-compatible. renaming or removing fields generates an 
exception as the class is being deserialized. If you specify your own serial 
werializable on your Serializable class, be sure to have some unit tests for 
backward compatibility every time you change the class.
due to the nature of serialization, don’t expect constructors to be called when 
an object is deserialized. If you have initialization code in constructors that are 
required for your object to function properly, you may need to refactor the code out 
of the constructor to allow proper execution after construction. The reason is that 
in the deserialization process, the deserialized objects are “restored” internally (not 
created) and do not invoke constructors.

Download 3.2 Mb.

Do'stlaringiz bilan baham:
1   ...   148   149   150   151   152   153   154   155   ...   245




Ma'lumotlar bazasi mualliflik huquqi bilan himoyalangan ©fayllar.org 2024
ma'muriyatiga murojaat qiling