JSON deserialization with generics
1、 Background
Today, the garden of boredom raised a question, involving the following examples:
public static void main(String[] args) {
List list = JSONObject.parseObject(jsonString, List.class);
System.out.println(list);
}
The class library of fastjson is used in the example.
Why does IDEA give the following warning and how to solve it?
Some students said that it would be better to suppress this warning by using suppression annotation directly.
Just suppress the warning????
2、 Analysis
2.1 Something strange must have a demon
IDEA will not give a warning prompt for no reason. The reason for the warning is shown in the figure above.
Assign a List without generics to a List with generics. The Java compiler does not know whether the actual List without generics returned on the right conforms to the List constraint with generics.
When first is assigned to third, it cannot be guaranteed that the first element conforms to the constraints of the List, that is, the list is full of Strings.
If you execute the above code, you will find no error reported, haha.
However, if you use a foreach loop or an iterator to take a String loop, a type conversion exception will occur.
Type conversion exception?
We use IDEA's jclasslib decompile plug-in to get the code of the main function.
From the logic of the foreach loop corresponding to lines 42 to 76, it can be seen that the underlying layer uses the iterator of List to traverse, takes out each element, and then forcibly converts it to String type, stores it at the location of the local variable table index 4, and then prints it.
If you are not familiar with decompilation, you can go to the target directory, double-click the compiled class file, and decompile using the plug-in provided by IDEA.
This confirms the above statement, obviously in String each=(String) var3. next(); There is a type conversion exception.
3、 Solution
3.1 Guess verification
We guess whether we can pass generics as parameters to fastjson in some way so that some return value of fastjson has generics, so as to solve this alarm?
Obviously, we need to look in the source code. The following methods are found in the JSONObject class.
With the analysis in the second part, you can easily think of
The List constructed by JSONObject. parseObject (jsonString, List. class) stores JSONObject elements. The bottom layer of the foreach loop uses iterators to traverse each element and forcibly convert it to User type, which is a type conversion exception.
So why can't fastjson help us convert to Listtype?
Some people said that "because of generic erasure, there is no generic information, so it is impossible to reverse construct the original type".
In fact, look at JSONObject. parseObject (jsonString, List. class); The first parameter is a string, and the second parameter is List.class. There is no generic information provided to fastjson at all.
As the tool function itself, how can you guess what type should be stored in the List?
Therefore, if you can tell it the type of a generic type in some way, it can help you deserialize it into a real type.
Use ` JSONObject. parseObject (jsonString, new TypeReference
Today, the garden of boredom raised a question, involving the following examples:
public static void main(String[] args) {
List
System.out.println(list);
}
The class library of fastjson is used in the example.
Why does IDEA give the following warning and how to solve it?
Some students said that it would be better to suppress this warning by using suppression annotation directly.
Just suppress the warning????
2、 Analysis
2.1 Something strange must have a demon
IDEA will not give a warning prompt for no reason. The reason for the warning is shown in the figure above.
Assign a List without generics to a List with generics. The Java compiler does not know whether the actual List without generics returned on the right conforms to the List constraint with generics.
When first is assigned to third, it cannot be guaranteed that the first element conforms to the constraints of the List, that is, the list is full of Strings.
If you execute the above code, you will find no error reported, haha.
However, if you use a foreach loop or an iterator to take a String loop, a type conversion exception will occur.
Type conversion exception?
We use IDEA's jclasslib decompile plug-in to get the code of the main function.
From the logic of the foreach loop corresponding to lines 42 to 76, it can be seen that the underlying layer uses the iterator of List to traverse, takes out each element, and then forcibly converts it to String type, stores it at the location of the local variable table index 4, and then prints it.
If you are not familiar with decompilation, you can go to the target directory, double-click the compiled class file, and decompile using the plug-in provided by IDEA.
This confirms the above statement, obviously in String each=(String) var3. next(); There is a type conversion exception.
3、 Solution
3.1 Guess verification
We guess whether we can pass generics as parameters to fastjson in some way so that some return value of fastjson has generics, so as to solve this alarm?
Obviously, we need to look in the source code. The following methods are found in the JSONObject class.
With the analysis in the second part, you can easily think of
The List constructed by JSONObject. parseObject (jsonString, List. class) stores JSONObject elements. The bottom layer of the foreach loop uses iterators to traverse each element and forcibly convert it to User type, which is a type conversion exception.
So why can't fastjson help us convert to List
Some people said that "because of generic erasure, there is no generic information, so it is impossible to reverse construct the original type".
In fact, look at JSONObject. parseObject (jsonString, List. class); The first parameter is a string, and the second parameter is List.class. There is no generic information provided to fastjson at all.
As the tool function itself, how can you guess what type should be stored in the List?
Therefore, if you can tell it the type of a generic type in some way, it can help you deserialize it into a real type.
Use ` JSONObject. parseObject (jsonString, new TypeReference
- (){
});` Yes.
Therefore, we use TypeReference not only to eliminate warnings, but also to inform fastjson of the specific types of generics and deserialize the types of generics correctly.
So what is the underlying principle? Let's take a look
Through the code and comments, we learned that:
Create an empty anonymous subclass. Embed the type parameter into the anonymous inheritance structure, which can be rebuilt even if the type is erased at runtime.
Back to the parseObject function, you can see that this type is used at the bottom.
3.2 Draw inferences from one instance
Many other frameworks will use similar methods to obtain generic types.
You can look at other gson libraries
Look at the com. google. gson. reflect. TypeToken class. Is it familiar?
In addition, in addition to the JSON deserialization scenario, we also have similar requirements for obtaining generic parameters. Can we use similar methods?
4、 Summary
I hope you can pay attention to IDEA's warning.
When encountering problems, you can think from a more reasonable perspective and understand the nature of the problem.
You can draw inferences from one instance and use it flexibly when learning a problem.
Related Articles
-
A detailed explanation of Hadoop core architecture HDFS
Knowledge Base Team
-
What Does IOT Mean
Knowledge Base Team
-
6 Optional Technologies for Data Storage
Knowledge Base Team
-
What Is Blockchain Technology
Knowledge Base Team
Explore More Special Offers
-
Short Message Service(SMS) & Mail Service
50,000 email package starts as low as USD 1.99, 120 short messages start at only USD 1.00