1. Serialization and Deserialization
Serialization: refers to the java object data in the heap memory. Store the pair in a disk file in some way, or pass it to other network nodes (network transmission). This process is called serialization, which usually refers to the process of converting a data structure or object into binary.
即將對(duì)象轉(zhuǎn)化為二進(jìn)制,用于保存,或者網(wǎng)絡(luò)傳輸。
Deserialization: The process of restoring the object data in the disk file or the object data on the network node to the Java object model. That is, the process of converting the binary string generated during the serialization process into a data structure or object
與序列化相反,將二進(jìn)制轉(zhuǎn)化成對(duì)象。
2. The role of serialization
① Want to store memory When the objects in are saved to a file or database;
② When you want to use sockets to transmit objects on the network;
③ When you want to transmit objects through RMI
一些應(yīng)用場(chǎng)景,涉及到將對(duì)象轉(zhuǎn)化成二進(jìn)制,序列化保證了能夠成功讀取到保存的對(duì)象。
3. Java serialization implementation
To achieve serialization of objects, the most direct operation is to implement the Serializable interface
Use objects in the IO stream Streams can implement serialization operations, save objects to files, and then read them out.
First create an object and implement the Serializable interface:
import java.io.Serializable; public class User implements Serializable{ private static final long serialVersionUID = 1L; private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "User [name=" + name + ", age=" + age + "]"; } }
Use object stream to write a tool class for saving and reading objects:
import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; public class SerializeUtil { // 保存對(duì)象,序列化 public static void saveObject(Object object) throws Exception { ObjectOutputStream out = null; FileOutputStream fout = null; try { fout = new FileOutputStream("D:/1.txt"); out = new ObjectOutputStream(fout); out.writeObject(object); } finally { fout.close(); out.close(); } } // 讀取對(duì)象,反序列化 public static Object readObject() throws Exception { ObjectInputStream in = null; FileInputStream fin = null; try { fin = new FileInputStream("D:/1.txt"); in = new ObjectInputStream(fin); Object object = in.readObject(); return object; } finally { fin.close(); in.close(); } } }
Test:
public class Main { public static void main(String[] args) { User user = new User(); user.setName("旭旭寶寶"); user.setAge(33); // 保存 try { SerializeUtil.saveObject(user); } catch (Exception e) { System.out.println("保存時(shí)異常:" + e.getMessage()); } // 讀取 User userObject; try { userObject = (User) SerializeUtil.readObject(); System.out.println(userObject); } catch (Exception e) { System.out.println("讀取時(shí)異常:" + e.getMessage()); } } }
Test results:
Here we successfully saved the object to a file and then read it out. If we do not implement the serialization interface at this time, an exception will occur. We cancel the implemented Serialiable interface code:
public class User { private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "User [name=" + name + ", age=" + age + "]"; } }
Test the Main method again:
You can see that an error is reported at this time, use e.printStackTrace( );View the details of the exception:
You can see the Unknown Source. Because it is not serialized, it cannot be saved and read.
4. The role of serialization ID
As you can see, when we serialize, we add a serialVersionUID field, which is the serialization ID
private static final long serialVersionUID = 1L;
This serialization ID plays a key role, it determines whether deserialization can be successful! Java's serialization mechanism verifies version consistency by judging the serialVersionUID of the runtime class. During deserialization, the JVM will compare the serialVersionUID in the incoming byte stream with the serialVersionUID in the local entity class. If If they are the same, they are considered consistent and can be deserialized. Otherwise, an exception of inconsistent serialized versions will be reported.
即序列化ID是為了保證成功進(jìn)行反序列化
5. Default serialization ID
When we do not explicitly define a variable named "serialVersionUID" and type long in an entity class , the Java serialization mechanism will automatically generate a serialVersionUID based on the compiled class as a serialization version comparison. In this case, only the classes generated by the same compilation will generate the same serialVersionUID. For example, when we write a class, as time goes by, we need to add other fields to the local class due to changes in requirements. At this time, serialVersionUID will be inconsistent during deserialization, causing deserialization to fail. So how to solve it? Just add a "serialVersionUID" variable to the local class, the value remains unchanged, and serialization and deserialization can be performed.
如果沒有顯示指定serialVersionUID,會(huì)自動(dòng)生成一個(gè)。 只有同一次編譯生成的class才會(huì)生成相同的serialVersionUID。 但是如果出現(xiàn)需求變動(dòng),Bean類發(fā)生改變,則會(huì)導(dǎo)致反序列化失敗。為了不出現(xiàn)這類的問題,所以我們最好還是顯式的指定一個(gè) serialVersionUID。
6. Other issues with serialization
1. Static variables will not be serialized (static, transient)
2. When a The parent class implements serialization, and the subclass automatically implements serialization. There is no need to explicitly implement the Serializable interface.
3. When the instance variables of an object refer to other objects, when the object is serialized, the referenced object is also serialized.
子類序列化時(shí): 如果父類沒有實(shí)現(xiàn)Serializable接口,沒有提供默認(rèn)構(gòu)造函數(shù),那么子類的序列化會(huì)出錯(cuò); 如果父類沒有實(shí)現(xiàn)Serializable接口,提供了默認(rèn)的構(gòu)造函數(shù),那么子類可以序列化,父類的成員變量不會(huì)被序列化。如果父類 實(shí)現(xiàn)了Serializable接口,則父類和子類都可以序列化。
7. Use a more efficient serialization framework—Protostuff
In fact, Java’s native serialization method (by implementing the Serialiable interface) is not as efficient as Not the highest.
There is a project on github to analyze serialization efficiency: https://github.com/eishay/jvm-serializers/wiki
Watch it The one with the best performance is colfer developed by Google, but because colfer is too difficult to use, most people use the protostuff serialization framework. To apply the framework, two libraries (core and runtime) need to be introduced.
①github address: https://github.com/protostuff/protostuff
③If you use Maven, add dependencies:
<dependency> <groupId>io.protostuff</groupId> <artifactId>protostuff-core</artifactId> <version>1.5.9</version> </dependency>
<dependency> <groupId>io.protostuff</groupId> <artifactId>protostuff-core</artifactId> <version>1.5.9</version> </dependency>
Modify Main code
import com.dyuproject.protostuff.LinkedBuffer; import com.dyuproject.protostuff.ProtobufIOUtil; import com.dyuproject.protostuff.ProtostuffIOUtil; import com.dyuproject.protostuff.Schema; import com.dyuproject.protostuff.runtime.RuntimeSchema; public class Main { public static void main(String[] args) { User user = new User(); user.setName("旭旭寶寶"); user.setAge(33); Schema<User> schema = RuntimeSchema.getSchema(User.class); // 保存對(duì)象,序列化,轉(zhuǎn)化二進(jìn)制數(shù)據(jù) LinkedBuffer buffer = LinkedBuffer.allocate(512); final byte[] protostuff; try { protostuff = ProtobufIOUtil.toByteArray(user, schema, buffer); } finally { buffer.clear(); } // 讀取對(duì)象,反序列化 User userObject = schema.newMessage(); ProtostuffIOUtil.mergeFrom(protostuff, userObject, schema); System.out.println(userObject); } }
User class does not implement the Serializable interface
public class User { private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "User [name=" + name + ", age=" + age + "]"; } }
Test results:
若要要整合Redis使用,也可以寫成一個(gè)工具類:
import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import com.dyuproject.protostuff.LinkedBuffer; import com.dyuproject.protostuff.ProtobufIOUtil; import com.dyuproject.protostuff.Schema; import com.dyuproject.protostuff.runtime.RuntimeSchema; public class SerializeUtil { private static Map<Class<?>, Schema<?>> cachedSchema = new ConcurrentHashMap<>(); @SuppressWarnings("unchecked") public static <T> byte[] serializer(T obj) { Class<T> clazz = (Class<T>) obj.getClass(); Schema<T> schema = getSchema(clazz); return ProtobufIOUtil.toByteArray(obj, schema, LinkedBuffer.allocate(256)); } public static <T> T deSerializer(byte[] bytes, Class<T> clazz) { T message; try { message = clazz.newInstance(); } catch (InstantiationException | IllegalAccessException e) { throw new RuntimeException(e); } Schema<T> schema = getSchema(clazz); ProtobufIOUtil.mergeFrom(bytes, message, schema); return message; } @SuppressWarnings("unchecked") public static <T> Schema<T> getSchema(Class<T> clazz) { Schema<T> schema = (Schema<T>) cachedSchema.get(clazz); if (schema == null) { schema = RuntimeSchema.createFrom(clazz); if (schema != null) { cachedSchema.put(clazz, schema); } } return schema; } }
這樣即使我們的User類就不用再實(shí)現(xiàn)Serialiable接口了,同樣可以進(jìn)行序列化,效率也更高。
php中文網(wǎng),大量的免費(fèi)Java入門教程,歡迎在線學(xué)習(xí)!
The above is the detailed content of How to serialize in java. For more information, please follow other related articles on the PHP Chinese website!

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)

Hot Topics

Optional can clearly express intentions and reduce code noise for null judgments. 1. Optional.ofNullable is a common way to deal with null objects. For example, when taking values ??from maps, orElse can be used to provide default values, so that the logic is clearer and concise; 2. Use chain calls maps to achieve nested values ??to safely avoid NPE, and automatically terminate if any link is null and return the default value; 3. Filter can be used for conditional filtering, and subsequent operations will continue to be performed only if the conditions are met, otherwise it will jump directly to orElse, which is suitable for lightweight business judgment; 4. It is not recommended to overuse Optional, such as basic types or simple logic, which will increase complexity, and some scenarios will directly return to nu.

There are three common methods to traverse Map in Java: 1. Use entrySet to obtain keys and values at the same time, which is suitable for most scenarios; 2. Use keySet or values to traverse keys or values respectively; 3. Use Java8's forEach to simplify the code structure. entrySet returns a Set set containing all key-value pairs, and each loop gets the Map.Entry object, suitable for frequent access to keys and values; if only keys or values are required, you can call keySet() or values() respectively, or you can get the value through map.get(key) when traversing the keys; Java 8 can use forEach((key,value)->

The core workaround for encountering java.io.NotSerializableException is to ensure that all classes that need to be serialized implement the Serializable interface and check the serialization support of nested objects. 1. Add implementsSerializable to the main class; 2. Ensure that the corresponding classes of custom fields in the class also implement Serializable; 3. Use transient to mark fields that do not need to be serialized; 4. Check the non-serialized types in collections or nested objects; 5. Check which class does not implement the interface; 6. Consider replacement design for classes that cannot be modified, such as saving key data or using serializable intermediate structures; 7. Consider modifying

In Java, Comparable is used to define default sorting rules internally, and Comparator is used to define multiple sorting logic externally. 1.Comparable is an interface implemented by the class itself. It defines the natural order by rewriting the compareTo() method. It is suitable for classes with fixed and most commonly used sorting methods, such as String or Integer. 2. Comparator is an externally defined functional interface, implemented through the compare() method, suitable for situations where multiple sorting methods are required for the same class, the class source code cannot be modified, or the sorting logic is often changed. The difference between the two is that Comparable can only define a sorting logic and needs to modify the class itself, while Compar

There are three common ways to parse JSON in Java: use Jackson, Gson, or org.json. 1. Jackson is suitable for most projects, with good performance and comprehensive functions, and supports conversion and annotation mapping between objects and JSON strings; 2. Gson is more suitable for Android projects or lightweight needs, and is simple to use but slightly inferior in handling complex structures and high-performance scenarios; 3.org.json is suitable for simple tasks or small scripts, and is not recommended for large projects because of its lack of flexibility and type safety. The choice should be decided based on actual needs.

How to quickly create new emails in Outlook is as follows: 1. The desktop version uses the shortcut key Ctrl Shift M to directly pop up a new email window; 2. The web version can create new emails in one-click by creating a bookmark containing JavaScript (such as javascript:document.querySelector("divrole='button'").click()); 3. Use browser plug-ins (such as Vimium, CrxMouseGestures) to trigger the "New Mail" button; 4. Windows users can also select "New Mail" by right-clicking the Outlook icon of the taskbar

Method reference is a way to simplify the writing of Lambda expressions in Java, making the code more concise. It is not a new syntax, but a shortcut to Lambda expressions introduced by Java 8, suitable for the context of functional interfaces. The core is to use existing methods directly as implementations of functional interfaces. For example, System.out::println is equivalent to s->System.out.println(s). There are four main forms of method reference: 1. Static method reference (ClassName::staticMethodName); 2. Instance method reference (binding to a specific object, instance::methodName); 3.

The volatile keyword in Java often feels a bit abstract, especially for those who are new to concurrent programming. In fact, its function is very clear: to ensure the visibility of variables between multiple threads. That is to say, when one thread modifies the variable value modified by volatile, other threads can see the change immediately. It is not a master key to solve all concurrency problems, but it is very useful in some scenarios. Let’s take a look at how to use it and where it is suitable for use. When do you need to use volatile? The most typical application scenario is the status flag, such as controlling whether the thread continues to run: privatevolatilebooleanrunning=true;
