Java’s serialization process is as follows:
Java’s deserialization process is as follows:
Note: Not all classes need to be serialized, there are two main reasons
1) Security Question. Some classes in Java are sensitive classes, and the object data of this type is inconvenient to be disclosed to the outside world. The serialized object data is easy to crack, and the security of the data cannot be guaranteed. Therefore, generally this type of object will not be serialized.
2) Resource issues. Objects can be created using serialized byte streams, and this creation is not restricted. Sometimes creating too many objects can cause big resource problems, so such objects are not suitable for serialization.
Serializable
Serializable is a serialization interface provided by Java. It is an empty interface that provides standard serialization and deserialization operations for objects.
Serialization process:
Person p = new Person("name","id"); File file = new File("cache.txt"); FileOutputStream output = new FileOutputStream(file); ObjectOutputStream objectOutputStream = new ObjectOutputStream(output); objectOutputStream.writeObject(p); output.close(); objectOutputStream.close();
Deserialization process:
File file = new File("cache.txt"); FileInputStream input= new FileInputStream(file); ObjectInputStream objectInputStream = new ObjectInputStream(input); Person p = (Person)objectInputStream.readObject(); System.out.println(p.getName()+"---"+p.getId()); input.close(); objectInputStream.close();
Class members that need to be serialized
When an object is serialized, not all members need to be converted into binary byte sequences, because in order to save storage or Transmission space and improve serialization efficiency, some unnecessary members do not need to be serialized. These include:
Static variables. Because static variables belong to the attributes of the class and do not belong to a specific instance, there is no need to serialize during serialization. During deserialization, you can directly obtain the static member reference of the class.
Method. A method is just a set of operations. The method does not depend on the object, and the operations will not be different depending on the object. During deserialization, the method information can also be obtained directly from the class.
Serialization of inheritance relationship
When the parent class implements Serializable, the child class is serialized and the parent class will also be serialized.
When the parent class does not implement Serializable, the subclass is serialized and the parent class will not be serialized.
Serialization of reference relationships
If a serialization operation is performed on a class that implements Serializable, it will be serialized at the same time. The reference class performs serialization operations. If the reference class does not implement the Serializable interface, the JVM will throw java.io.NotSerializableExeception.
class Person implements Serializable{ private String name; private Tool tool = new Tool(); } class Tool implements Serializable{ }
At this time, if the Person class is serialized, the Tool class will be serialized at the same time. If the Tool class does not implement the Serializable interface, an exception will be thrown.
Protect sensitive data:
After a class is added with a serialization identifier, all attribute information of the object of this class will be serialized and then stored locally or transmitted over the network. Then sometimes some fields in the object are sensitive information and should not be exposed. If it is also serialized, it can be easily cracked, thus causing security risks, such as common password fields.
Java provides a keyword transient, which is the transient keyword. This keyword turns off the serialization of the field so that protected information is not exposed through serialization.
Serialization Identification ID
Imagine this scenario: Both ends are transmitting serialized objects over the network. For some reason, the versions of the classes used by both ends are different. Assume that the receiver's classes have been deleted. field. When the sender sends the serialized byte stream of the object to the receiver, it cannot be parsed because the receiver's class is missing several fields.
Java requires that classes that implement the serialization interface must declare a serialVersionUID static attribute. If there is no such attribute, the JVM will automatically declare the attribute and assign a value to the attribute (different values ??will be assigned when the class changes). The value of this attribute is unique and is used to identify different serialization classes. Only if the serialization identifier of the class is exactly the same, Java will perform deserialization work. This is the role of the serialization identifier.
For the aforementioned scenario, assuming that the serialVersionUID is not declared manually, the JVM assigns different values ??to the serialVersionUID in the classes used by the sender and the receiver, and the deserialization fails. When serialVersionUID is manually assigned, deserialization can be successful even if the fields of the class change.
Custom serialization strategy
Custom serialization strategy
Java provides a set of effective mechanisms that allow customized methods to be used for corresponding processing during serialization and deserialization. After the transmission parties agree on the serialization strategy, they only need to add a set of methods to the serialization class that needs to be transmitted to implement this set of strategies. During serialization, these specified methods will be automatically called for serialization and deserialization. The method is as follows:
1) private void writeObject(ObjectOutputSteam out) throws IOException
在方法的內(nèi)部有重要的代碼:out.defaultWriteObject() //將對象數(shù)據(jù)以默認(rèn)方式寫入到輸出流中
2)private void readObject(ObjectInputStream in) throws IOException,ClassNotFoundException
同樣的,此方法內(nèi)部也有相似代碼:in.defaultReadObject(); //以默認(rèn)方式從輸入流中恢復(fù)對象
這兩個方法的作用分別是將特定的對象寫入到輸出流中以及從輸入流中恢復(fù)特定的對象,通過這兩個方法,用戶即可實現(xiàn)自定義的序列化。當(dāng)在實現(xiàn)Serializable接口的類中寫了上面兩個方法之后,序列化或反序列化該類時則會通過反射來調(diào)用這兩個方法,從而實現(xiàn)自定義序列化。
限制序列化對象的數(shù)量
我們看下面的單例模式:
public class Singleton implements Serializable { private volatile static Singleton mInstance; private Singleton() { } public static Singleton getInstance() { if (mInstance == null) { synchronized (Singleton.class) { if (mInstance == null) { mInstance = new Singleton(); } } } return mInstance; } }
此時通過反序列化獲取實例,則單例模式會失效。那該如何解決這個問題呢?
Java有一種機制,可以讓我們在序列化和反序列化時,可以根據(jù)自己的需要,寫入或讀取指定的實例。使用這種機制,需要在實現(xiàn)Serializable接口的類中添加兩個方法:
private Object readResolve() //如果用戶在序列化類中添加了該方法,則在進行反序列化時,使用該方法返回的對象,作為反序列化對象。
private Object writeReplace() //如果用戶在序列化類中添加了該方法,則在進行序列化時,序列化該類返回的對象。
再看使用了該機制的單例模式:
public class Singleton implements Serializable { private volatile static Singleton mInstance; private Singleton() { } public static Singleton getInstance() { if (mInstance == null) { synchronized (Singleton.class) { if (mInstance == null) { mInstance = new Singleton(); } } } return mInstance; } private Object readResolve() { return getInstance(); } private Object writeReplace() { return getInstance(); } }
此時的通過反序列化得到的對象也是同一個,即單例模式依然有效!
相關(guān)文章:
Java序列化Serializable和Externalizable區(qū)別的示例代碼

Hot AI Tools

Undress AI Tool
Undress images for free

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

To correctly handle JDBC transactions, you must first turn off the automatic commit mode, then perform multiple operations, and finally commit or rollback according to the results; 1. Call conn.setAutoCommit(false) to start the transaction; 2. Execute multiple SQL operations, such as INSERT and UPDATE; 3. Call conn.commit() if all operations are successful, and call conn.rollback() if an exception occurs to ensure data consistency; at the same time, try-with-resources should be used to manage resources, properly handle exceptions and close connections to avoid connection leakage; in addition, it is recommended to use connection pools and set save points to achieve partial rollback, and keep transactions as short as possible to improve performance.

Use classes in the java.time package to replace the old Date and Calendar classes; 2. Get the current date and time through LocalDate, LocalDateTime and LocalTime; 3. Create a specific date and time using the of() method; 4. Use the plus/minus method to immutably increase and decrease the time; 5. Use ZonedDateTime and ZoneId to process the time zone; 6. Format and parse date strings through DateTimeFormatter; 7. Use Instant to be compatible with the old date types when necessary; date processing in modern Java should give priority to using java.timeAPI, which provides clear, immutable and linear

Pre-formanceTartuptimeMoryusage, Quarkusandmicronautleadduetocompile-Timeprocessingandgraalvsupport, Withquarkusoftenperforminglightbetterine ServerLess scenarios.2.Thyvelopecosyste,

Networkportsandfirewallsworktogethertoenablecommunicationwhileensuringsecurity.1.Networkportsarevirtualendpointsnumbered0–65535,withwell-knownportslike80(HTTP),443(HTTPS),22(SSH),and25(SMTP)identifyingspecificservices.2.PortsoperateoverTCP(reliable,c

Java's garbage collection (GC) is a mechanism that automatically manages memory, which reduces the risk of memory leakage by reclaiming unreachable objects. 1.GC judges the accessibility of the object from the root object (such as stack variables, active threads, static fields, etc.), and unreachable objects are marked as garbage. 2. Based on the mark-clearing algorithm, mark all reachable objects and clear unmarked objects. 3. Adopt a generational collection strategy: the new generation (Eden, S0, S1) frequently executes MinorGC; the elderly performs less but takes longer to perform MajorGC; Metaspace stores class metadata. 4. JVM provides a variety of GC devices: SerialGC is suitable for small applications; ParallelGC improves throughput; CMS reduces

Choosing the right HTMLinput type can improve data accuracy, enhance user experience, and improve usability. 1. Select the corresponding input types according to the data type, such as text, email, tel, number and date, which can automatically checksum and adapt to the keyboard; 2. Use HTML5 to add new types such as url, color, range and search, which can provide a more intuitive interaction method; 3. Use placeholder and required attributes to improve the efficiency and accuracy of form filling, but it should be noted that placeholder cannot replace label.

Gradleisthebetterchoiceformostnewprojectsduetoitssuperiorflexibility,performance,andmoderntoolingsupport.1.Gradle’sGroovy/KotlinDSLismoreconciseandexpressivethanMaven’sverboseXML.2.GradleoutperformsMaveninbuildspeedwithincrementalcompilation,buildcac

defer is used to perform specified operations before the function returns, such as cleaning resources; parameters are evaluated immediately when defer, and the functions are executed in the order of last-in-first-out (LIFO); 1. Multiple defers are executed in reverse order of declarations; 2. Commonly used for secure cleaning such as file closing; 3. The named return value can be modified; 4. It will be executed even if panic occurs, suitable for recovery; 5. Avoid abuse of defer in loops to prevent resource leakage; correct use can improve code security and readability.
