Java 17 Recipes
Download 3.2 Mb. Pdf ko'rish
|
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: |
Ma'lumotlar bazasi mualliflik huquqi bilan himoyalangan ©fayllar.org 2024
ma'muriyatiga murojaat qiling
ma'muriyatiga murojaat qiling