-
Notifications
You must be signed in to change notification settings - Fork 1
/
fastjson.drawio
225 lines (225 loc) · 138 KB
/
fastjson.drawio
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
<mxfile host="Electron" modified="2024-11-07T09:01:32.005Z" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/21.6.5 Chrome/114.0.5735.243 Electron/25.3.1 Safari/537.36" etag="FwWrvOaNisfgfgRjSaMU" version="21.6.5" type="device">
<diagram name="第 1 页" id="g6lgx3qi2_SGSoq7ZiQh">
<mxGraphModel dx="3653" dy="683" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="O2tCoPHxbhI8zbObZZQl-1" value="<h1 style=""><font style="font-size: 16px;">Fastjson2</font><span style="font-size: 23px;">&nbsp;</span><font style="font-size: 12px;">(</font><font style="font-size: 12px;">2.0.53)</font></h1><div><font style="font-size: 12px;"><br></font></div>" style="text;html=1;strokeColor=none;fillColor=none;spacing=5;spacingTop=-20;whiteSpace=wrap;overflow=hidden;rounded=0;" parent="1" vertex="1">
<mxGeometry x="40" y="10" width="320" height="90" as="geometry" />
</mxCell>
<mxCell id="O2tCoPHxbhI8zbObZZQl-4" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="O2tCoPHxbhI8zbObZZQl-2" target="O2tCoPHxbhI8zbObZZQl-3" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="O2tCoPHxbhI8zbObZZQl-2" value="String jsonString = JSON.toJSONString(user);<br><font color="#007fff"><b>序列化</b></font>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontSize=11;" parent="1" vertex="1">
<mxGeometry x="40" y="120" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="O2tCoPHxbhI8zbObZZQl-12" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="O2tCoPHxbhI8zbObZZQl-3" target="O2tCoPHxbhI8zbObZZQl-11" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="O2tCoPHxbhI8zbObZZQl-13" value="1" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="O2tCoPHxbhI8zbObZZQl-12" vertex="1" connectable="0">
<mxGeometry x="0.25" y="2" relative="1" as="geometry">
<mxPoint x="12" y="-17" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="O2tCoPHxbhI8zbObZZQl-22" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" parent="1" source="O2tCoPHxbhI8zbObZZQl-3" target="O2tCoPHxbhI8zbObZZQl-21" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="O2tCoPHxbhI8zbObZZQl-24" value="..." style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="O2tCoPHxbhI8zbObZZQl-22" vertex="1" connectable="0">
<mxGeometry x="0.8772" y="1" relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="9sC5CoJF8o419bWHhUuv-7" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.75;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="O2tCoPHxbhI8zbObZZQl-3" target="9sC5CoJF8o419bWHhUuv-6" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="730" y="435" />
<mxPoint x="730" y="2720" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="O2tCoPHxbhI8zbObZZQl-3" value="<div style="font-size: 11px;">final ObjectWriterProvider <b>provider</b> = defaultObjectWriterProvider;</div><div style="font-size: 11px;">final JSONWriter.Context <b>context</b> = new JSONWriter.Context(<b>provider</b>);</div><div style="font-size: 11px;"><font color="#007fff"><b>// 1 创建JSON格式的Writer, ObjectWriter 借助 JSONWriter 对字段值序列化输出</b></font></div><div style="font-size: 11px;">try (JSONWriter <b>writer</b> = JSONWriter.of(<b>context</b>)) {</div><div style="font-size: 11px;">&nbsp; &nbsp; if (object == null) {</div><div style="font-size: 11px;">&nbsp; &nbsp; &nbsp; &nbsp; writer.writeNull();</div><div style="font-size: 11px;">&nbsp; &nbsp; } else {</div><div style="font-size: 11px;">&nbsp; &nbsp; &nbsp; &nbsp; writer.<b>rootObject</b> = object;</div><div style="font-size: 11px;">&nbsp; &nbsp; &nbsp; &nbsp; writer.<b>path</b> = JSONWriter.Path.ROOT;</div><div style="font-size: 11px;"><br style="font-size: 11px;"></div><div style="font-size: 11px;">&nbsp; &nbsp; &nbsp; &nbsp; Class&lt;?&gt; <b>valueClass</b> = object.getClass();</div><div style="font-size: 11px;"><font color="#007fff"><span style="font-weight: bold;"><span style="">&nbsp; &nbsp; &nbsp; &nbsp; </span></span>// 如果要序列化的对象是 JSONObject.class 且 features == 0</font></div><div style="font-size: 11px;">&nbsp; &nbsp; &nbsp; &nbsp; if (valueClass == JSONObject.class &amp;&amp; context.features == 0) {</div><div style="font-size: 11px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <b>writer</b>.<b>write</b>((JSONObject) object);</div><div style="font-size: 11px;">&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp;</div><div style="font-size: 11px;">&nbsp; &nbsp; &nbsp; &nbsp; <b><font color="#007fff">// 要序列化的对象非 JSONObject.class 或 features != 0</font></b><br></div><div style="font-size: 11px;"><span style=""><span style="white-space: pre;">&nbsp;&nbsp;&nbsp;&nbsp; </span></span>else {</div><div style="font-size: 11px;"><b><font color="#007fff"><span style="white-space: pre;">	</span>&nbsp; &nbsp; // 2 内部先看是否缓存过这个类型的 ObjectWriter, 有直接返回没有ASM创建类型然后类加载并实例化</font><br></b></div><div style="font-size: 11px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ObjectWriter&lt;?&gt; <b>objectWriter</b> = provider.<b>getObjectWriter</b>(</div><div style="font-size: 11px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; valueClass,&nbsp;<span style="background-color: initial;">valueClass,</span></div><div style="font-size: 11px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (defaultWriterFeatures &amp; JSONWriter.Feature.FieldBased.mask) != 0</div><div style="font-size: 11px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; );</div><div style="font-size: 11px;"><b><span style="white-space: pre;">	</span>&nbsp; &nbsp; <font color="#007fff">// 3 ObjectWriter 需要 JSONWriter 序列化输出</font></b></div><div style="font-size: 11px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <b>objectWriter</b>.<b>write</b>(writer, object, null, null, 0);</div><div style="font-size: 11px;">&nbsp; &nbsp; &nbsp; &nbsp; }</div><div style="font-size: 11px;">&nbsp; &nbsp; }</div><div style="font-size: 11px;">&nbsp; &nbsp; return writer.<b>toString</b>();</div><div style="font-size: 11px;">} catch (NullPointerException | NumberFormatException e) {</div><div style="font-size: 11px;">&nbsp; &nbsp; throw new JSONException("JSON#toJSONString cannot serialize '" + object + "'", e);</div><div style="font-size: 11px;">}</div>" style="rounded=1;whiteSpace=wrap;html=1;align=left;fontSize=11;arcSize=3;" parent="1" vertex="1">
<mxGeometry x="280" y="120" width="440" height="420" as="geometry" />
</mxCell>
<mxCell id="O2tCoPHxbhI8zbObZZQl-5" value="<p style="margin: 4px 0px 0px; text-align: center;"><b>JSONFactory</b><br style="font-size: 11px;"></p><hr style="font-size: 11px;"><p style="margin: 0px 0px 0px 4px;"><br></p><p style="margin: 0px 0px 0px 4px;"><span style="background-color: initial;">static long defaultWriterFeatures;</span><br></p><p style="margin: 0px 0px 0px 4px;"><span style="background-color: initial;">static String defaultWriterFormat;<br></span></p><p style="margin: 0px 0px 0px 4px;"><span style="background-color: initial;">static ZoneId defaultWriterZoneId;<br></span></p><p style="margin: 0px 0px 0px 4px; font-size: 11px;"><span style="background-color: initial;">...</span></p><p style="margin: 0px 0px 0px 4px; font-size: 11px;"><span style="background-color: initial;">static final ObjectWriterProvider defaultObjectWriterProvider = new ObjectWriterProvider();</span><br></p><p style="margin: 0px 0px 0px 4px;">static final ObjectReaderProvider defaultObjectReaderProvider = new ObjectReaderProvider();</p><p style="margin: 0px 0px 0px 4px;">...</p><hr style="font-size: 11px;"><p style="margin: 0px 0px 0px 4px; font-size: 11px;"><br></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=11;fontFamily=Helvetica;html=1;whiteSpace=wrap;" parent="1" vertex="1">
<mxGeometry x="-520" y="120" width="480" height="280" as="geometry" />
</mxCell>
<mxCell id="O2tCoPHxbhI8zbObZZQl-8" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;endArrow=block;endFill=1;" parent="1" source="O2tCoPHxbhI8zbObZZQl-6" target="O2tCoPHxbhI8zbObZZQl-7" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="O2tCoPHxbhI8zbObZZQl-27" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;endArrow=open;endFill=0;" parent="1" source="O2tCoPHxbhI8zbObZZQl-6" target="O2tCoPHxbhI8zbObZZQl-26" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="O2tCoPHxbhI8zbObZZQl-6" value="<p style="margin: 4px 0px 0px; text-align: center; font-size: 11px;"><b style="font-size: 11px;">ObjectWriterProvider</b><br style="font-size: 11px;"></p><hr style="font-size: 11px;"><p style="margin: 0px 0px 0px 4px; font-size: 11px;"><font color="#007fff">// 缓存的通过Setter绑定数据的类型的ObjectWriter</font></p><p style="margin: 0px 0px 0px 4px; font-size: 11px;">final ConcurrentMap&lt;Type, ObjectWriter&gt; <b>cache</b> = new ConcurrentHashMap&lt;&gt;();</p><p style="border-color: var(--border-color); margin: 0px 0px 0px 4px;"><font style="border-color: var(--border-color);" color="#007fff">// 缓存的通过Filed绑定数据的类型的ObjectWriter</font></p><p style="margin: 0px 0px 0px 4px; font-size: 11px;">final ConcurrentMap&lt;Type, ObjectWriter&gt; <b>cacheFieldBased</b> = new ConcurrentHashMap&lt;&gt;();</p><p style="margin: 0px 0px 0px 4px; font-size: 11px;">final ConcurrentMap&lt;Class, Class&gt; <b>mixInCache</b> = new ConcurrentHashMap&lt;&gt;();、</p><p style="margin: 0px 0px 0px 4px; font-size: 11px;"><font color="#007fff"><b>// 默认使用的 ObjectWriterCreator,有2种实现, 默认使用ObjectWriterCreatorASM.INSTANCE, 通过 ASM 生成ObjectWriter;</b></font></p><p style="margin: 0px 0px 0px 4px; font-size: 11px;"><font color="#007fff"><b>如果通过系统属性 fastjson2.creator(默认 asm)设置 reflect 或 lambda 则通过 ObjectWriterCreator 生成&nbsp; ObjectWriter</b></font></p><p style="margin: 0px 0px 0px 4px; font-size: 11px;"><font color="#007fff">旧版本还有其他两种实现 ObejctWriterCreatorLambda ObjectWriterCreatorDynamicCompile (但是新版本这两种实现已经从核心代码移除了,可能转移了)</font></p><p style="margin: 0px 0px 0px 4px; font-size: 11px;">final ObjectWriterCreator <b>creator</b>;</p><p style="margin: 0px 0px 0px 4px; font-size: 11px;"><font color="#007fff">//</font></p><p style="margin: 0px 0px 0px 4px; font-size: 11px;">final List&lt;ObjectWriterModule&gt; <b>modules</b> = new ArrayList&lt;&gt;();</p><p style="margin: 0px 0px 0px 4px; font-size: 11px;">PropertyNamingStrategy <b>namingStrategy</b>;</p><p style="margin: 0px 0px 0px 4px; font-size: 11px;"><br style="font-size: 11px;"></p><p style="margin: 0px 0px 0px 4px; font-size: 11px;">boolean disableReferenceDetect = JSONFactory.isDisableReferenceDetect();</p><p style="margin: 0px 0px 0px 4px; font-size: 11px;">boolean disableArrayMapping = JSONFactory.isDisableArrayMapping();</p><p style="margin: 0px 0px 0px 4px; font-size: 11px;">boolean disableJSONB = JSONFactory.isDisableJSONB();</p><p style="margin: 0px 0px 0px 4px; font-size: 11px;">boolean disableAutoType = JSONFactory.isDisableAutoType();</p><p style="margin: 0px 0px 0px 4px; font-size: 11px;"><br style="font-size: 11px;"></p><p style="margin: 0px 0px 0px 4px; font-size: 11px;">volatile long userDefineMask;</p><p style="margin: 0px 0px 0px 4px; font-size: 11px;">boolean alphabetic = JSONFactory.isDefaultWriterAlphabetic();</p><hr style="font-size: 11px;"><p style="margin: 0px 0px 0px 4px; font-size: 11px;"><br></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=11;fontFamily=Helvetica;html=1;whiteSpace=wrap;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="-1040" y="240" width="480" height="360" as="geometry" />
</mxCell>
<mxCell id="O2tCoPHxbhI8zbObZZQl-7" value="<p style="margin: 4px 0px 0px; text-align: center;"><b>ObjectCodecProvider (I)</b><br style="font-size: 11px;"></p><hr style="font-size: 11px;"><p style="margin: 0px 0px 0px 4px; font-size: 11px;"></p><p style="margin: 0px 0px 0px 4px;">Class getMixIn(Class target);<br></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=11;fontFamily=Helvetica;html=1;whiteSpace=wrap;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" vertex="1">
<mxGeometry x="-1040" y="120" width="480" height="80" as="geometry" />
</mxCell>
<mxCell id="O2tCoPHxbhI8zbObZZQl-9" value="<p style="margin: 4px 0px 0px; text-align: center;"><b>JSONWriter (A)</b><br style="font-size: 11px;"></p><hr style="font-size: 11px;"><p style="margin: 0px 0px 0px 4px; font-size: 11px;"><font color="#007fff">// JSONWriter$Context 实例</font></p><p style="margin: 0px 0px 0px 4px;">public final Context <b>context</b>;</p><p style="margin: 0px 0px 0px 4px;">public final boolean utf8;</p><p style="margin: 0px 0px 0px 4px;"><font color="#007fff">// 是否使用 UTF-16 编码格式</font></p><p style="margin: 0px 0px 0px 4px;">public final boolean <b>utf16</b>;</p><p style="margin: 0px 0px 0px 4px;"><font color="#007fff">// 是否使用 JSONB 格式,即 JSON 二进制格式,默认false</font></p><p style="margin: 0px 0px 0px 4px;">public final boolean jsonb;</p><p style="margin: 0px 0px 0px 4px;"><font color="#007fff">// 是否使用单引号,默认是false 默认使用双引号</font></p><p style="margin: 0px 0px 0px 4px;">public final boolean <b>useSingleQuote</b>;</p><p style="margin: 0px 0px 0px 4px;"><font color="#007fff">//</font></p><p style="margin: 0px 0px 0px 4px;">public final SymbolTable symbolTable;</p><p style="margin: 0px 0px 0px 4px;"><font color="#007fff">// 序列化编码格式,默认使用 UTF-16 编码格式</font></p><p style="margin: 0px 0px 0px 4px;">protected final Charset <b>charset</b>;</p><p style="margin: 0px 0px 0px 4px;">protected final char quote;</p><p style="margin: 0px 0px 0px 4px;"><font color="#007fff">//</font></p><p style="margin: 0px 0px 0px 4px;">protected final int <b>maxArraySize</b>;</p><p style="margin: 0px 0px 0px 4px;"><br></p><p style="margin: 0px 0px 0px 4px;">protected boolean startObject;</p><p style="margin: 0px 0px 0px 4px;">protected int level;</p><p style="margin: 0px 0px 0px 4px;">protected int off;</p><p style="margin: 0px 0px 0px 4px;"><font color="#007fff">// 要序列化的目标对象</font></p><p style="margin: 0px 0px 0px 4px;">protected Object <b>rootObject</b>;</p><p style="margin: 0px 0px 0px 4px;">protected IdentityHashMap&lt;Object, Path&gt; refs;</p><p style="margin: 0px 0px 0px 4px;">protected Path path;</p><p style="margin: 0px 0px 0px 4px;">protected String lastReference;</p><p style="margin: 0px 0px 0px 4px;"><font color="#007fff">// 是否格式化,默认是压缩形式</font></p><p style="margin: 0px 0px 0px 4px;">protected boolean pretty;</p><p style="margin: 0px 0px 0px 4px;">protected int <b>indent</b>;</p><p style="margin: 0px 0px 0px 4px;">protected Object attachment;</p><hr style="font-size: 11px;"><p style="margin: 0px 0px 0px 4px; font-size: 11px;"><br></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=11;fontFamily=Helvetica;html=1;whiteSpace=wrap;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1">
<mxGeometry x="-1480" y="120" width="400" height="480" as="geometry" />
</mxCell>
<mxCell id="O2tCoPHxbhI8zbObZZQl-10" value="<p style="margin: 4px 0px 0px; text-align: center;"><b>JSONWriter$Context</b></p><hr style="font-size: 11px;"><p style="margin: 0px 0px 0px 4px; font-size: 11px;"><br></p><p style="margin: 0px 0px 0px 4px;">public final ObjectWriterProvider <b>provider</b>;</p><p style="margin: 0px 0px 0px 4px;">DateTimeFormatter dateFormatter;</p><p style="margin: 0px 0px 0px 4px;">String dateFormat;</p><p style="margin: 0px 0px 0px 4px;">Locale locale;</p><p style="margin: 0px 0px 0px 4px;">boolean dateFormatMillis;</p><p style="margin: 0px 0px 0px 4px;">boolean dateFormatISO8601;</p><p style="margin: 0px 0px 0px 4px;">boolean dateFormatUnixTime;</p><p style="margin: 0px 0px 0px 4px;">boolean formatyyyyMMddhhmmss19;</p><p style="margin: 0px 0px 0px 4px;">boolean formatHasDay;</p><p style="margin: 0px 0px 0px 4px;">boolean formatHasHour;</p><p style="margin: 0px 0px 0px 4px;"><font color="#007fff">// 里面使用 bit 表示一些配置, 具体参考Feature,比如第21bit 表示是否使用单引号&nbsp;</font></p><p style="margin: 0px 0px 0px 4px;">long <b>features</b>;</p><p style="margin: 0px 0px 0px 4px;">ZoneId zoneId;</p><p style="margin: 0px 0px 0px 4px;">int maxLevel = 2048;</p><p style="margin: 0px 0px 0px 4px;">boolean hasFilter;</p><p style="margin: 0px 0px 0px 4px;">PropertyPreFilter propertyPreFilter;</p><p style="margin: 0px 0px 0px 4px;">PropertyFilter propertyFilter;</p><p style="margin: 0px 0px 0px 4px;">NameFilter nameFilter;</p><p style="margin: 0px 0px 0px 4px;">ValueFilter valueFilter;</p><p style="margin: 0px 0px 0px 4px;">BeforeFilter beforeFilter;</p><p style="margin: 0px 0px 0px 4px;">AfterFilter afterFilter;</p><p style="margin: 0px 0px 0px 4px;">LabelFilter labelFilter;</p><p style="margin: 0px 0px 0px 4px;">ContextValueFilter contextValueFilter;</p><p style="margin: 0px 0px 0px 4px;">ContextNameFilter contextNameFilter;</p><hr style="font-size: 11px;"><p style="margin: 0px 0px 0px 4px; font-size: 11px;"><br></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=11;fontFamily=Helvetica;html=1;whiteSpace=wrap;" parent="1" vertex="1">
<mxGeometry x="-1920" y="120" width="400" height="400" as="geometry" />
</mxCell>
<mxCell id="O2tCoPHxbhI8zbObZZQl-11" value="<div style=""><div style="">public static JSONWriter of(Context context) {</div><div style="">&nbsp; &nbsp; ...</div><div style="">&nbsp; &nbsp; JSONWriter jsonWriter;</div><div style="">&nbsp; &nbsp; if (<b>JVM_VERSION == 8</b>) {<font color="#007fff"> // java.specification.version</font></div><div style=""><font color="#007fff"><span style=""><span style="white-space: pre;">&nbsp;&nbsp;&nbsp;&nbsp; </span></span>// String.class value字段不为空 &amp;&amp; 非安卓VM &amp;&amp; 非OpenJ9虚拟机<br></font></div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; if (FIELD_STRING_VALUE != null &amp;&amp; !ANDROID &amp;&amp; !OPENJ9) {</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; jsonWriter = new <b>JSONWriterUTF16JDK8UF</b>(context);</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; } else {</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; jsonWriter = new JSONWriterUTF16JDK8(context);</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; }</div><div style="">&nbsp; &nbsp; } else if ((context.features &amp; OptimizedForAscii.mask) != 0) {</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; ...</div><div style="">&nbsp; &nbsp; } else {</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; ...</div><div style="">&nbsp; &nbsp; }</div><div style="">&nbsp; &nbsp; return <b>jsonWriter</b>;</div><div style="">}</div></div>" style="rounded=1;whiteSpace=wrap;html=1;align=left;fontSize=11;arcSize=3;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="760" y="120" width="440" height="240" as="geometry" />
</mxCell>
<mxCell id="O2tCoPHxbhI8zbObZZQl-15" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;endArrow=block;endFill=1;" parent="1" source="O2tCoPHxbhI8zbObZZQl-14" target="O2tCoPHxbhI8zbObZZQl-9" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="O2tCoPHxbhI8zbObZZQl-14" value="<p style="margin: 4px 0px 0px; text-align: center;"><b>JSONWriterUTF16</b><br style="font-size: 11px;"></p><hr style="font-size: 11px;"><p style="margin: 0px 0px 0px 4px; font-size: 11px;"><br></p><p style="margin: 0px 0px 0px 4px;">static final char[] REF_PREF = "{\"$ref\":".toCharArray();</p><p style="margin: 0px 0px 0px 4px;">static final int[] HEX256;</p><p style="margin: 0px 0px 0px 4px;"><font color="#007fff">// 初始化为 char[8192]</font></p><p style="margin: 0px 0px 0px 4px;">protected char[] <b>chars</b>;</p><p style="margin: 0px 0px 0px 4px;">final CacheItem <b>cacheItem</b>;</p><hr style="font-size: 11px;"><p style="margin: 0px 0px 0px 4px; font-size: 11px;"><br></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=11;fontFamily=Helvetica;html=1;whiteSpace=wrap;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="-1480" y="640" width="400" height="160" as="geometry" />
</mxCell>
<mxCell id="O2tCoPHxbhI8zbObZZQl-17" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;endArrow=block;endFill=1;" parent="1" source="O2tCoPHxbhI8zbObZZQl-16" target="O2tCoPHxbhI8zbObZZQl-14" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="O2tCoPHxbhI8zbObZZQl-16" value="<p style="margin: 4px 0px 0px; text-align: center;"><b>JSONWriterUTF16JDK8UF</b><br style="font-size: 11px;"></p><hr style="font-size: 11px;"><p style="margin: 0px 0px 0px 4px; font-size: 11px;"><br></p><hr style="font-size: 11px;"><p style="margin: 0px 0px 0px 4px;">public void writeString(String str)<br></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=11;fontFamily=Helvetica;html=1;whiteSpace=wrap;" parent="1" vertex="1">
<mxGeometry x="-1480" y="840" width="400" height="80" as="geometry" />
</mxCell>
<mxCell id="O2tCoPHxbhI8zbObZZQl-18" value="<p style="margin: 4px 0px 0px; text-align: center;"><b>JSONWriter$Path</b></p><hr style="font-size: 11px;"><p style="margin: 0px 0px 0px 4px; font-size: 11px;"><font color="#007fff">// 根对象: $,可以结合 JSONPath&nbsp;</font></p><p style="margin: 0px 0px 0px 4px;">public static final Path ROOT = new Path(null, "$");</p><p style="margin: 0px 0px 0px 4px;">public static final Path MANGER_REFERNCE = new Path(null, "#");</p><p style="margin: 0px 0px 0px 4px;"><br></p><p style="margin: 0px 0px 0px 4px;">public final Path parent;</p><p style="margin: 0px 0px 0px 4px;">final String name;</p><p style="margin: 0px 0px 0px 4px;">final int index;</p><p style="margin: 0px 0px 0px 4px;">String fullPath;</p><p style="margin: 0px 0px 0px 4px;"><br></p><p style="margin: 0px 0px 0px 4px;">Path child0;</p><p style="margin: 0px 0px 0px 4px;">Path child1;</p><hr style="font-size: 11px;"><p style="margin: 0px 0px 0px 4px; font-size: 11px;"><br></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=11;fontFamily=Helvetica;html=1;whiteSpace=wrap;" parent="1" vertex="1">
<mxGeometry x="-1920" y="560" width="400" height="240" as="geometry" />
</mxCell>
<mxCell id="O2tCoPHxbhI8zbObZZQl-19" value="<p style="margin: 4px 0px 0px; text-align: center;"><b>JSONWriter$</b><b style="background-color: initial;">Feature (E)</b></p><hr style="font-size: 11px;"><p style="margin: 0px 0px 0px 4px; font-size: 11px;"><b><font color="#007fff">用于序列化格式控制</font></b></p><p style="margin: 0px 0px 0px 4px; font-size: 11px;"><br></p><p style="margin: 0px 0px 0px 4px;">FieldBased(1),<span style="white-space: pre;">	</span>&nbsp;<font color="#007fff">// 反序列化时是否使用字段而不是方法进行数据绑定</font></p><p style="margin: 0px 0px 0px 4px;">IgnoreNoneSerializable(1 &lt;&lt; 1),</p><p style="margin: 0px 0px 0px 4px;">ErrorOnNoneSerializable(1 &lt;&lt; 2),</p><p style="margin: 0px 0px 0px 4px;">BeanToArray(1 &lt;&lt; 3),</p><p style="margin: 0px 0px 0px 4px;">WriteNulls(1 &lt;&lt; 4),</p><p style="margin: 0px 0px 0px 4px;">WriteMapNullValue(1 &lt;&lt; 4),</p><p style="margin: 0px 0px 0px 4px;">BrowserCompatible(1 &lt;&lt; 5),</p><p style="margin: 0px 0px 0px 4px;">NullAsDefaultValue(1 &lt;&lt; 6),</p><p style="margin: 0px 0px 0px 4px;">WriteBooleanAsNumber(1 &lt;&lt; 7),</p><p style="margin: 0px 0px 0px 4px;">WriteNonStringValueAsString(1 &lt;&lt; 8),</p><p style="margin: 0px 0px 0px 4px;">WriteClassName(1 &lt;&lt; 9),</p><p style="margin: 0px 0px 0px 4px;">NotWriteRootClassName(1 &lt;&lt; 10),</p><p style="margin: 0px 0px 0px 4px;">NotWriteHashMapArrayListClassName(1 &lt;&lt; 11),</p><p style="margin: 0px 0px 0px 4px;">NotWriteDefaultValue(1 &lt;&lt; 12),</p><p style="margin: 0px 0px 0px 4px;">WriteEnumsUsingName(1 &lt;&lt; 13),</p><p style="margin: 0px 0px 0px 4px;">WriteEnumUsingToString(1 &lt;&lt; 14),</p><p style="margin: 0px 0px 0px 4px;">IgnoreErrorGetter(1 &lt;&lt; 15),</p><p style="margin: 0px 0px 0px 4px;">PrettyFormat(1 &lt;&lt; 16),</p><p style="margin: 0px 0px 0px 4px;">ReferenceDetection(1 &lt;&lt; 17),</p><p style="margin: 0px 0px 0px 4px;">WriteNameAsSymbol(1 &lt;&lt; 18),</p><p style="margin: 0px 0px 0px 4px;">WriteBigDecimalAsPlain(1 &lt;&lt; 19),</p><p style="margin: 0px 0px 0px 4px;">UseSingleQuotes(1 &lt;&lt; 20),</p><p style="margin: 0px 0px 0px 4px;">MapSortField(1 &lt;&lt; 21),</p><p style="margin: 0px 0px 0px 4px;">WriteNullListAsEmpty(1 &lt;&lt; 22),</p><p style="margin: 0px 0px 0px 4px;">WriteNullStringAsEmpty(1 &lt;&lt; 23),</p><p style="margin: 0px 0px 0px 4px;">WriteNullNumberAsZero(1 &lt;&lt; 24),</p><p style="margin: 0px 0px 0px 4px;">WriteNullBooleanAsFalse(1 &lt;&lt; 25),</p><p style="margin: 0px 0px 0px 4px;">NotWriteEmptyArray(1 &lt;&lt; 26),</p><p style="margin: 0px 0px 0px 4px;">IgnoreEmpty(1L &lt;&lt; 26),</p><p style="margin: 0px 0px 0px 4px;">WriteNonStringKeyAsString(1 &lt;&lt; 27),</p><p style="margin: 0px 0px 0px 4px;">WritePairAsJavaBean(1L &lt;&lt; 28),</p><p style="margin: 0px 0px 0px 4px;">OptimizedForAscii(1L &lt;&lt; 29),</p><p style="margin: 0px 0px 0px 4px;">EscapeNoneAscii(1L &lt;&lt; 30),</p><p style="margin: 0px 0px 0px 4px;">WriteByteArrayAsBase64(1L &lt;&lt; 31),</p><p style="margin: 0px 0px 0px 4px;">IgnoreNonFieldGetter(1L &lt;&lt; 32),</p><p style="margin: 0px 0px 0px 4px;">LargeObject(1L &lt;&lt; 33),</p><p style="margin: 0px 0px 0px 4px;">WriteLongAsString(1L &lt;&lt; 34),</p><p style="margin: 0px 0px 0px 4px;">BrowserSecure(1L &lt;&lt; 35),</p><p style="margin: 0px 0px 0px 4px;">WriteEnumUsingOrdinal(1L &lt;&lt; 36),</p><p style="margin: 0px 0px 0px 4px;">WriteThrowableClassName(1L &lt;&lt; 37),</p><p style="margin: 0px 0px 0px 4px;">UnquoteFieldName(1L &lt;&lt; 38),</p><p style="margin: 0px 0px 0px 4px;">NotWriteSetClassName(1L &lt;&lt; 39),</p><p style="margin: 0px 0px 0px 4px;">NotWriteNumberClassName(1L &lt;&lt; 40),</p><p style="margin: 0px 0px 0px 4px;">SortMapEntriesByKeys(1L &lt;&lt; 41);</p><hr style="font-size: 11px;"><p style="margin: 0px 0px 0px 4px; font-size: 11px;"><br></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=11;fontFamily=Helvetica;html=1;whiteSpace=wrap;" parent="1" vertex="1">
<mxGeometry x="-2360" y="120" width="400" height="680" as="geometry" />
</mxCell>
<mxCell id="O2tCoPHxbhI8zbObZZQl-32" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1.002;exitY=0.88;exitDx=0;exitDy=0;exitPerimeter=0;" parent="1" source="O2tCoPHxbhI8zbObZZQl-21" target="O2tCoPHxbhI8zbObZZQl-31" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="9sC5CoJF8o419bWHhUuv-2" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.998;exitY=0.888;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;exitPerimeter=0;" parent="1" source="O2tCoPHxbhI8zbObZZQl-21" target="9sC5CoJF8o419bWHhUuv-1" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="O2tCoPHxbhI8zbObZZQl-21" value="<div style=""><div style=""><div>private ObjectWriter <b>getObjectWriterInternal</b>(Type objectType, Class objectClass, boolean fieldBased) {</div><div><font color="#007fff"><b>&nbsp; &nbsp; // 通过父类型创建对应的ObjectWriter</b></font></div><div>&nbsp; &nbsp; Class superclass = objectClass.<b>getSuperclass</b>();</div><div><font color="#007fff">&nbsp; &nbsp; // 枚举类型 ...</font></div><div><br></div><div><font color="#007fff">&nbsp; &nbsp; // 非枚举类型</font></div><div><font color="#007fff">&nbsp; &nbsp; // 如果设置了通过Filed绑定数据,先检查类型是否支持这么做</font></div><div>&nbsp; &nbsp; final String className = objectClass.getName();</div><div>&nbsp; &nbsp; if (<b>fieldBased</b>) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; if (superclass != null</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &amp;&amp; superclass != Object.class</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &amp;&amp; "com.google.protobuf.GeneratedMessageV3".equals(superclass.getName())) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fieldBased = false;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; } else {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; switch (className) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case "springfox.documentation.spring.web.json.Json":</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case "cn.hutool.json.JSONArray":</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case "cn.hutool.json.JSONObject":</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case "cn.hutool.core.map.CaseInsensitiveMap":</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case "cn.hutool.core.map.CaseInsensitiveLinkedMap":</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fieldBased = false;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; default:</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; } else {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; switch (className) {</div><div><font color="#007fff"><span style=""><span style="">&nbsp;&nbsp;&nbsp;&nbsp;</span></span>&nbsp; &nbsp; // 这种类型必须通过 Field 绑定数据</font><br></div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case "org.springframework.core.ResolvableType":</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fieldBased = true;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; default:</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; }</div><div><br></div><div><font color="#007fff"><b>&nbsp; &nbsp; //还是先判断缓存,不存在再创建类型的ObjectWriter</b></font></div><div>&nbsp; &nbsp; ObjectWriter objectWriter = fieldBased</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ? cacheFieldBased.get(objectType)</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : cache.get(objectType);</div><div>&nbsp; &nbsp; if (objectWriter != null) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; return objectWriter;</div><div>&nbsp; &nbsp; }</div><div><font color="#007fff">&nbsp; &nbsp; // 序列化目标类型是否是代理类型,这里支持识别 Spring CgLib、Javasist、Hibernate等代理类</font></div><div>&nbsp; &nbsp; if (TypeUtils.<b>isProxy</b>(objectClass)) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; ...</div><div>&nbsp; &nbsp; }</div><div><br></div><div>&nbsp; &nbsp; boolean useModules = true;</div><div>&nbsp; &nbsp; if (fieldBased) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; if (Iterable.class.isAssignableFrom(objectClass)</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &amp;&amp; !Collection.class.isAssignableFrom(objectClass)) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; useModules = false;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; }</div><div><br></div><div><font color="#007fff"><b>&nbsp; &nbsp; // 是否使用模块,初始化时默认会注册一个&nbsp;ObjectWriterBaseModule</b></font></div><div>&nbsp; &nbsp; if (<b>useModules</b>) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; for (int i = 0; i &lt; modules.size(); i++) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ObjectWriterModule module = modules.get(i);</div><div><b><font color="#007fff"><span style=""><span style="white-space: pre;">&nbsp;&nbsp;&nbsp;&nbsp;</span></span>&nbsp; &nbsp; // 内部根据objectType判断应该使用哪种ObjectWriter实现,定义了很多类型都有对应的ObjectWriter单例实现</font></b><br></div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; objectWriter = module.<b>getObjectWriter</b>(objectType, objectClass);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (objectWriter != null) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ObjectWriter previous = fieldBased</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ? cacheFieldBased.putIfAbsent(objectType, objectWriter)</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : cache.putIfAbsent(objectType, objectWriter);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (previous != null) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; objectWriter = previous;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return objectWriter;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; }</div><div><font color="#007fff">&nbsp; &nbsp; // 为特殊类型创建特殊的ObjectWriter,先略</font></div><div>&nbsp; &nbsp; switch (className) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; case "com.google.common.collect.HashMultimap":</div><div>&nbsp; &nbsp; &nbsp; &nbsp; case "com.google.common.collect.LinkedListMultimap":</div><div>&nbsp; &nbsp; &nbsp; &nbsp; case "com.google.common.collect.LinkedHashMultimap":</div><div>&nbsp; &nbsp; &nbsp; &nbsp; case "com.google.common.collect.ArrayListMultimap":</div><div>&nbsp; &nbsp; &nbsp; &nbsp; case "com.google.common.collect.TreeMultimap":</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; objectWriter = GuavaSupport.createAsMapWriter(objectClass);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; case "com.google.common.collect.AbstractMapBasedMultimap$RandomAccessWrappedList":</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; objectWriter = ObjectWriterImplList.INSTANCE;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; case "com.alibaba.fastjson.JSONObject":</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; objectWriter = ObjectWriterImplMap.of(objectClass);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; case "android.net.Uri$OpaqueUri":</div><div>&nbsp; &nbsp; &nbsp; &nbsp; case "android.net.Uri$HierarchicalUri":</div><div>&nbsp; &nbsp; &nbsp; &nbsp; case "android.net.Uri$StringUri":</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; objectWriter = ObjectWriterImplToString.INSTANCE;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; case "com.clickhouse.data.value.UnsignedLong":</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; objectWriter = new ObjectWriterImplToString(true);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; default:</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;</div><div>&nbsp; &nbsp; }</div><div>&nbsp; &nbsp; if (objectWriter == null</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &amp;&amp; (!fieldBased)</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &amp;&amp; Map.class.isAssignableFrom(objectClass)</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &amp;&amp; BeanUtils.isExtendedMap(objectClass)) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; return ObjectWriterImplMap.of(objectClass);</div><div>&nbsp; &nbsp; }</div><div><br></div><div><font color="#007fff">&nbsp; &nbsp; // 上面的判断都不符合此测试中的 User.class&nbsp;</font></div><div>&nbsp; &nbsp; if (objectWriter == null) {</div><div><font color="#007fff"><b>&nbsp; &nbsp; &nbsp; &nbsp; // 默认是&nbsp;ObjectWriterCreatorASM.INSTANCE,内部通过 ASM 生成 ObjectWriter 实现类</b></font></div><div>&nbsp; &nbsp; &nbsp; &nbsp; ObjectWriterCreator creator = <b>getCreator</b>();</div><div>&nbsp; &nbsp; &nbsp; &nbsp; objectWriter = creator.<b>createObjectWriter</b>(</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; objectClass,</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fieldBased ? JSONWriter.Feature.FieldBased.mask : 0,</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this</div><div>&nbsp; &nbsp; &nbsp; &nbsp; );</div><div>&nbsp; &nbsp; &nbsp; &nbsp; ObjectWriter previous = fieldBased</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ? cacheFieldBased.putIfAbsent(objectType, objectWriter)</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : cache.putIfAbsent(objectType, objectWriter);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; if (previous != null) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; objectWriter = previous;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; }</div><div>&nbsp; &nbsp; return objectWriter;</div><div>}</div></div></div>" style="rounded=1;whiteSpace=wrap;html=1;align=left;fontSize=11;arcSize=3;" parent="1" vertex="1">
<mxGeometry x="760" y="400" width="440" height="1720" as="geometry" />
</mxCell>
<mxCell id="O2tCoPHxbhI8zbObZZQl-25" value="<p style="margin: 4px 0px 0px; text-align: center;"><b>ObjectWriterModule</b><br style="font-size: 11px;"></p><hr style="font-size: 11px;"><p style="margin: 0px 0px 0px 4px; font-size: 11px;"><br></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=11;fontFamily=Helvetica;html=1;whiteSpace=wrap;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" vertex="1">
<mxGeometry x="-520" y="440" width="480" height="80" as="geometry" />
</mxCell>
<mxCell id="O2tCoPHxbhI8zbObZZQl-28" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;endArrow=block;endFill=1;dashed=1;" parent="1" source="O2tCoPHxbhI8zbObZZQl-26" target="O2tCoPHxbhI8zbObZZQl-25" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="O2tCoPHxbhI8zbObZZQl-26" value="<p style="margin: 4px 0px 0px; text-align: center;"><b>ObjectWriterBaseModule</b><br style="font-size: 11px;"></p><hr style="font-size: 11px;"><p style="margin: 0px 0px 0px 4px;"><font color="#007fff">指定了一些类型对应的 ObjectWriter 实现</font></p><p style="margin: 0px 0px 0px 4px;"><font color="#007fff"><br></font></p><p style="margin: 0px 0px 0px 4px;">static ObjectWriterAdapter STACK_TRACE_ELEMENT_WRITER;<br></p><p style="margin: 0px 0px 0px 4px;">final ObjectWriterProvider provider;</p><p style="margin: 0px 0px 0px 4px;">final WriterAnnotationProcessor <b>annotationProcessor</b>;</p><hr style="font-size: 11px;"><p style="margin: 0px 0px 0px 4px;"><br></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=11;fontFamily=Helvetica;html=1;whiteSpace=wrap;" parent="1" vertex="1">
<mxGeometry x="-520" y="560" width="480" height="120" as="geometry" />
</mxCell>
<mxCell id="O2tCoPHxbhI8zbObZZQl-29" value="<font color="#007fff" style="font-size: 10px;">这里的user 是自定义 User 类型,父类Object,<br>内部包含两个字段,String username; Integer age;&nbsp;<br>以及对应的 Getter Setter 方法</font>" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="40" y="180" width="250" height="60" as="geometry" />
</mxCell>
<mxCell id="O2tCoPHxbhI8zbObZZQl-30" value="<font color="#007fff">从这个过程可以看到很多类都有自己的 ObjectWriter 单例实现<br>估计是这个序列化的流程很多类无法复用,必须针对地进行定制,<br>所以 Fastjson 的源码量才会那么大(仅核心非测试代码就有十几万行)</font>" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="1210" y="400" width="400" height="60" as="geometry" />
</mxCell>
<mxCell id="O2tCoPHxbhI8zbObZZQl-31" value="<div style=""><div style=""><div>public ObjectWriterCreator getCreator() {</div><div>&nbsp; &nbsp; ObjectWriterCreator contextCreator = JSONFactory.<b>getContextWriterCreator</b>();</div><div>&nbsp; &nbsp; if (contextCreator != null) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; return contextCreator;</div><div>&nbsp; &nbsp; }</div><div>&nbsp; &nbsp; return <b>creator</b>;</div><div>}</div></div></div>" style="rounded=1;whiteSpace=wrap;html=1;align=left;fontSize=11;arcSize=3;" parent="1" vertex="1">
<mxGeometry x="1241" y="1820" width="439" height="120" as="geometry" />
</mxCell>
<mxCell id="9sC5CoJF8o419bWHhUuv-4" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="9sC5CoJF8o419bWHhUuv-1" target="9sC5CoJF8o419bWHhUuv-3" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="9sC5CoJF8o419bWHhUuv-1" value="<div style=""><div style=""><b><font color="#007fff">分析待序列化字段,并生成对应字段的 FieldWriter</font></b></div><div style="">...</div><div style="">return jitWriter(objectClass, provider, <b>beanInfo</b>, <b>fieldWriters</b>, <b>writerFeatures</b>);<br></div></div>" style="rounded=1;whiteSpace=wrap;html=1;align=left;fontSize=11;arcSize=12;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="1241" y="1960" width="439" height="60" as="geometry" />
</mxCell>
<mxCell id="9sC5CoJF8o419bWHhUuv-3" value="<div style=""><div style=""><div><font color="#007fff"><b>// 先通过ASM生成 ObjectWriter 类,比如此测试生成的是&nbsp;</b></font><font color="#007fff"><b>OWG_1_2_User</b></font></div><div>cw.visit(Opcodes.V1_8,</div><div>&nbsp; &nbsp; &nbsp; &nbsp; Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL + Opcodes.ACC_SUPER,</div><div>&nbsp; &nbsp; &nbsp; &nbsp; classNameType,</div><div>&nbsp; &nbsp; &nbsp; &nbsp; objectWriterSupper,</div><div>&nbsp; &nbsp; &nbsp; &nbsp; INTERFACES</div><div>);</div><div><font color="#007fff">... 省略了很多生成 ObjectWriter 类的代码 ...</font></div><div>byte[] code = cw.<b>toByteArray</b>();<br></div><div><div>{ <font color="#007fff"><b>// 这里是自己手动添加一些代码将字节码打印到class文件</b></font></div><div>&nbsp; &nbsp; try {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; String classPath = "/tmp/fastjson2/generated/" + classNameType + ".class";</div><div>&nbsp; &nbsp; &nbsp; &nbsp; Path path = Paths.get(classPath);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; if (!Files.exists(path)) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Files.createDirectories(path.getParent());</div><div>&nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; &nbsp; &nbsp; Files.write(path, code);</div><div>&nbsp; &nbsp; } catch (IOException e) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; e.printStackTrace();</div><div>&nbsp; &nbsp; }</div><div>}</div></div><div><font color="#007fff"><b>// 然后加载</b></font></div><div>Class&lt;?&gt; deserClass = classLoader.defineClassPublic(classNameFull, code, 0, code.length);<br></div><div><font color="#007fff"><b>// 实例化</b></font></div><div><div>ObjectWriterAdapter <b>objectWriter</b> = (ObjectWriterAdapter) constructor.<b>newInstance</b>(</div><div>&nbsp; &nbsp; &nbsp; &nbsp; objectClass,</div><div>&nbsp; &nbsp; &nbsp; &nbsp; <b>beanInfo</b>.typeKey,</div><div>&nbsp; &nbsp; &nbsp; &nbsp; <b>beanInfo</b>.typeName,</div><div>&nbsp; &nbsp; &nbsp; &nbsp; <b>writerFeatures</b>,</div><div>&nbsp; &nbsp; &nbsp; &nbsp; <b>fieldWriters</b></div><div>);</div><div>if (beanInfo.serializeFilters != null) {</div><div>&nbsp; &nbsp; configSerializeFilters(beanInfo, objectWriter);</div><div>}</div><div>return <b>objectWriter</b>;</div></div></div></div>" style="rounded=1;whiteSpace=wrap;html=1;align=left;fontSize=11;arcSize=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="1720" y="1750" width="440" height="480" as="geometry" />
</mxCell>
<mxCell id="LhijFJnAiS_UeM6sa_ox-15" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.998;exitY=0.622;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="1" source="9sC5CoJF8o419bWHhUuv-6" target="LhijFJnAiS_UeM6sa_ox-14">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="9sC5CoJF8o419bWHhUuv-6" value="<div style=""><div style=""><div style="font-size: 10px;"><font color="#007fff"><b>//这是测试中 Fastjson2 针对 User 类型动态生成的 ObjectWriter 类型</b></font></div><div style="font-size: 10px;">public final class <b>OWG_1_2_User</b> extends <b>ObjectWriter2</b> implements <b>ObjectWriter</b> {</div><div style="font-size: 10px;">&nbsp; &nbsp; <font color="#007fff">// 参数依次是 序列化目标对象Class类型、beanInfo.typeKey、beanInfo.typeName、writeFeature、fieldWriters</font></div><div style="font-size: 10px;">&nbsp; &nbsp; public OWG_1_2_User(Class var1, String var2, String var3, long var4, List var6) {</div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; super(var1, var2, var3, var4, var6);</div><div style="font-size: 10px;">&nbsp; &nbsp; }</div><div style="font-size: 10px;"><br style="font-size: 10px;"></div><div style="font-size: 10px;">&nbsp; &nbsp; public void writeJSONB(JSONWriter var1, Object var2, Object var3, Type var4, long var5) {</div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; ...</div><div style="font-size: 10px;">&nbsp; &nbsp; }</div><div style="font-size: 10px;"><font color="#007fff"><b>&nbsp; &nbsp; // 这里只关注这个序列化方法</b></font></div><div style="font-size: 10px;">&nbsp; &nbsp; public void <b>write</b>(JSONWriter <b>var1</b>, Object var2, Object var3, Type var4, long var5) {</div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; long <b>var8</b> = var1.getFeatures();</div><div style="font-size: 10px;"><font color="#007fff"><span style=""><span style="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span></span>// 是否使用单引号</font><br></div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; boolean var10 = !var1.useSingleQuote &amp;&amp; (var8 &amp; 274878955520L) == 0L;</div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; long var17;</div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; int var12 = (var17 = (var8 &amp; 4096L) - 0L) == 0L ? 0 : (var17 &lt; 0L ? -1 : 1);</div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; if (var12 != 0) {</div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; boolean var13 = false;</div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; } else {</div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; long var18;</div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int var16 = (var18 = (var8 &amp; 80L) - 0L) == 0L ? 0 : (var18 &lt; 0L ? -1 : 1);</div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; }</div><div style="font-size: 10px;"><br style="font-size: 10px;"></div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; if ((var8 &amp; 274877939712L) != 0L) {</div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; super.<b>write</b>(var1, var2, var3, var4, var5);</div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; } else if (var1.jsonb) {</div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if ((var8 &amp; 8L) != 0L) {</div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.writeArrayMappingJSONB(var1, var2, var3, var4, var5);</div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } else {</div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.writeJSONB(var1, var2, var3, var4, var5);</div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; } else if ((var8 &amp; 8L) != 0L) {</div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.<b>writeArrayMapping</b>(var1, var2, var3, var4, var5);</div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; } else if (this.hasFilter(var1)) { <font color="#007fff">// Filter用于写拓展</font></div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.<b>writeWithFilter</b>(var1, var2, var3, var4, var5);</div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; } else {</div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if ((var8 &amp; 2L) != 0L) {</div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var1.writeNull();</div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } else if ((var8 &amp; 4L) != 0L) {</div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.errorOnNoneSerializable();</div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } else {</div><div style="font-size: 10px;"><font color="#007fff">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// JSON开始大括号的左括号:“{”,如果 pretty = true, 还需要换行缩进</font></div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var1.<b>startObject</b>();&nbsp;&nbsp;</div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; boolean var7 = true;</div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (var2 != null &amp;&amp; var2.getClass() != var4 &amp;&amp; var1.isWriteTypeInfo(var2, var4, var5)) {</div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var7 = this.writeTypeInfo(var1) ^ true;</div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div style="font-size: 10px;"><font color="#007fff"><span style=""><span style="">&nbsp;&nbsp;&nbsp;&nbsp;</span></span><span style=""><span style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span></span>// 写第一个字段 age, 字段经过字典序排序</font><br style="font-size: 10px;"></div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Integer var14;</div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if ((var14 = ((User)var2).<b>getAge</b>()) == null) {</div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if ((var8 &amp; 16777296L) != 0L) {</div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var1.writeName3Raw(var10 ? 63919404572962L : 63940879409447L);</div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var1.writeNumberNull();</div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } else { <font style="font-size: 10px;" color="#007fff">// 先写字段名再写字段值, "age": ASCII 16进制编码依次是 22616765223a</font></div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var1.<b>writeName3Raw</b>(var10 ? <b>63919404572962L</b> : 63940879409447L);</div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var1.<b>writeInt32</b>(var14);</div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div style="font-size: 10px;"><font color="#007fff"><span style=""><span style="">&nbsp;&nbsp;&nbsp;&nbsp;</span></span><span style=""><span style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span></span>// 写第二个字段 username</font><br style="font-size: 10px;"></div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String var15;</div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if ((var15 = ((User)var2).<b>getUsername</b>()) != null) {</div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if ((var8 &amp; 67108864L) == 0L || !var15.isEmpty()) {</div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var1.<b>writeName8Raw</b>(7308604897285731189L);</div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var1.<b>writeString</b>((char[])JDKUtils.UNSAFE.getObject(var15, 12L));</div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } else if ((var8 &amp; 8388688L) != 0L &amp;&amp; (var8 &amp; 4096L) == 0L) {</div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var1.writeName8Raw(7308604897285731189L);</div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (var1.isEnabled(8388672L)) {</div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var1.writeString("");</div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } else {</div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var1.writeStringNull();</div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div style="font-size: 10px;"><font color="#007fff"><span style=""><span style="">&nbsp;&nbsp;&nbsp;&nbsp;</span></span><span style=""><span style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span></span>// 写最后一个大括号的右括号:“}”<br style="font-size: 10px;"></font></div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var1.<b>endObject</b>();</div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div style="font-size: 10px;"><br style="font-size: 10px;"></div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; }</div><div style="font-size: 10px;">&nbsp; &nbsp; }</div><div style="font-size: 10px;"><br style="font-size: 10px;"></div><div style="font-size: 10px;">&nbsp; &nbsp; public void writeArrayMappingJSONB(JSONWriter var1, Object var2, Object var3, Type var4, long var5) {</div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; ...</div><div style="font-size: 10px;">&nbsp; &nbsp; }</div><div style="font-size: 10px;"><br style="font-size: 10px;"></div><div style="font-size: 10px;">&nbsp; &nbsp; public void writeArrayMapping(JSONWriter var1, Object var2, Object var3, Type var4, long var5) <br>&nbsp; &nbsp; {</div><div style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; ...</div><div style="font-size: 10px;">&nbsp; &nbsp; }</div><div style="font-size: 10px;">}</div></div></div>" style="rounded=1;whiteSpace=wrap;html=1;align=left;fontSize=10;arcSize=1;fillColor=#f5f5f5;fontColor=#333333;strokeColor=#666666;" parent="1" vertex="1">
<mxGeometry x="760" y="2160" width="439" height="1120" as="geometry" />
</mxCell>
<mxCell id="LhijFJnAiS_UeM6sa_ox-2" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;endArrow=block;endFill=1;dashed=1;" edge="1" parent="1" source="9sC5CoJF8o419bWHhUuv-8" target="LhijFJnAiS_UeM6sa_ox-1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="LhijFJnAiS_UeM6sa_ox-9" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.25;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;endArrow=open;endFill=0;" edge="1" parent="1" source="9sC5CoJF8o419bWHhUuv-8" target="9sC5CoJF8o419bWHhUuv-9">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="9sC5CoJF8o419bWHhUuv-8" value="<p style="margin: 4px 0px 0px; text-align: center;"><b>ObjectWriterAdapter&lt;T&gt;</b><br style="font-size: 11px;"></p><hr style="font-size: 11px;"><p style="margin: 0px 0px 0px 4px;"><font color="#007fff"><b>对某个类型的序列化器,内部包含 FiledWriter</b></font></p><p style="margin: 0px 0px 0px 4px;"><font color="#007fff"><br></font></p><p style="margin: 0px 0px 0px 4px;"><font color="#007fff">// Filter 用于拓展序列化操作</font></p><p style="margin: 0px 0px 0px 4px;">boolean hasFilter;</p><p style="margin: 0px 0px 0px 4px;">PropertyPreFilter propertyPreFilter;</p><p style="margin: 0px 0px 0px 4px;">PropertyFilter propertyFilter;</p><p style="margin: 0px 0px 0px 4px;">NameFilter nameFilter;</p><p style="margin: 0px 0px 0px 4px;">ValueFilter valueFilter;</p><p style="margin: 0px 0px 0px 4px;"><br></p><p style="margin: 0px 0px 0px 4px;">static final String TYPE = "@type";</p><p style="margin: 0px 0px 0px 4px;"><font color="#007fff">// ObjectWriter 对应的目标类型</font></p><p style="margin: 0px 0px 0px 4px;">final Class <b>objectClass</b>;</p><p style="margin: 0px 0px 0px 4px;"><font color="#007fff">//&nbsp;需要序列化的字段对应的 FieldWriter</font></p><p style="margin: 0px 0px 0px 4px;">final List&lt;FieldWriter&gt; <b>fieldWriters</b>;</p><p style="margin: 0px 0px 0px 4px;">protected final FieldWriter[] <b>fieldWriterArray</b>;</p><p style="margin: 0px 0px 0px 4px;"><br></p><p style="margin: 0px 0px 0px 4px;">final String typeKey;</p><p style="margin: 0px 0px 0px 4px;">byte[] typeKeyJSONB;</p><p style="margin: 0px 0px 0px 4px;"><font color="#007fff">// 目标类型的全限定名</font></p><p style="margin: 0px 0px 0px 4px;">protected final String typeName;</p><p style="margin: 0px 0px 0px 4px;">protected final long typeNameHash;</p><p style="margin: 0px 0px 0px 4px;">protected long typeNameSymbolCache;</p><p style="margin: 0px 0px 0px 4px;">protected final byte[] typeNameJSONB;</p><p style="margin: 0px 0px 0px 4px;"><br></p><p style="margin: 0px 0px 0px 4px;">byte[] nameWithColonUTF8;</p><p style="margin: 0px 0px 0px 4px;">char[] nameWithColonUTF16;</p><p style="margin: 0px 0px 0px 4px;"><font color="#007fff">// 格式控制指标</font></p><p style="margin: 0px 0px 0px 4px;">final long <b>features</b>;</p><p style="margin: 0px 0px 0px 4px;"><br></p><p style="margin: 0px 0px 0px 4px;">final long[] hashCodes;</p><p style="margin: 0px 0px 0px 4px;">final short[] mapping;</p><p style="margin: 0px 0px 0px 4px;"><br></p><p style="margin: 0px 0px 0px 4px;">final boolean hasValueField;</p><p style="margin: 0px 0px 0px 4px;">final boolean serializable;</p><p style="margin: 0px 0px 0px 4px;">final boolean containsNoneFieldGetter;</p><p style="margin: 0px 0px 0px 4px;">final boolean googleCollection;</p><hr style="font-size: 11px;"><p style="margin: 0px 0px 0px 4px; font-size: 11px;"><br></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=11;fontFamily=Helvetica;html=1;whiteSpace=wrap;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1">
<mxGeometry x="-520" y="1120" width="480" height="560" as="geometry" />
</mxCell>
<mxCell id="9sC5CoJF8o419bWHhUuv-9" value="<p style="margin: 4px 0px 0px; text-align: center;"><b>Field</b><b style="background-color: initial;">Writer (A)</b></p><hr style="font-size: 11px;"><p style="margin: 0px 0px 0px 4px;"><b><font color="#007fff">字段序列化器,有针对基本数据类型字段的、有针对对象类型字段的、有针对一些特殊对象类型字段的,用于生成 ObejctWriter 动态类型中字段序列化代码</font></b></p><p style="margin: 0px 0px 0px 4px;"><br></p><p style="margin: 0px 0px 0px 4px;">public final String fieldName;</p><p style="margin: 0px 0px 0px 4px;">public final Type fieldType;</p><p style="margin: 0px 0px 0px 4px;">public final Class fieldClass;</p><p style="margin: 0px 0px 0px 4px;">public final long features;</p><p style="margin: 0px 0px 0px 4px;">public final int ordinal;</p><p style="margin: 0px 0px 0px 4px;">public final String format;</p><p style="margin: 0px 0px 0px 4px;">public final Locale locale;</p><p style="margin: 0px 0px 0px 4px;">public final DecimalFormat decimalFormat;</p><p style="margin: 0px 0px 0px 4px;">public final String label;</p><p style="margin: 0px 0px 0px 4px;">public final Field field;</p><p style="margin: 0px 0px 0px 4px;">public final Method method;</p><p style="margin: 0px 0px 0px 4px;">protected final long fieldOffset;</p><p style="margin: 0px 0px 0px 4px;">protected final boolean primitive;</p><p style="margin: 0px 0px 0px 4px;"><br></p><p style="margin: 0px 0px 0px 4px;">final long hashCode;</p><p style="margin: 0px 0px 0px 4px;">final byte[] nameWithColonUTF8;</p><p style="margin: 0px 0px 0px 4px;">final char[] nameWithColonUTF16;</p><p style="margin: 0px 0px 0px 4px;">final byte[] nameJSONB;</p><p style="margin: 0px 0px 0px 4px;">long nameSymbolCache;</p><p style="margin: 0px 0px 0px 4px;"><br></p><p style="margin: 0px 0px 0px 4px;">final boolean fieldClassSerializable;</p><p style="margin: 0px 0px 0px 4px;">final JSONWriter.Path rootParentPath;</p><p style="margin: 0px 0px 0px 4px;"><br></p><p style="margin: 0px 0px 0px 4px;">final boolean symbol;</p><p style="margin: 0px 0px 0px 4px;">final boolean trim;</p><p style="margin: 0px 0px 0px 4px;">final boolean raw;</p><p style="margin: 0px 0px 0px 4px;">final boolean managedReference;</p><p style="margin: 0px 0px 0px 4px;">final boolean backReference;</p><p style="margin: 0px 0px 0px 4px;"><br></p><p style="margin: 0px 0px 0px 4px;">transient JSONWriter.Path path;</p><p style="margin: 0px 0px 0px 4px;">volatile ObjectWriter <b>initObjectWriter</b>;</p><p style="margin: 0px 0px 0px 4px;">Object defaultValue;</p><p style="margin: 0px 0px 0px 4px;"><br></p><hr style="font-size: 11px;"><p style="margin: 0px 0px 0px 4px; font-size: 11px;"><br></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=11;fontFamily=Helvetica;html=1;whiteSpace=wrap;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1">
<mxGeometry x="-1040" y="720" width="480" height="520" as="geometry" />
</mxCell>
<mxCell id="9sC5CoJF8o419bWHhUuv-10" value="<font color="#007fff" style="font-size: 10px;"><div style="">序列化主体逻辑可以分为3部分:</div><div style="">1)通过Class解析一个类型需要序列化的部分(比如公共基本类型字段、有实现 Getter 方法的私有基本类型字段、对象类型字段、继承的字段等等),针对每个字段会创建一个 FieldWriter 实现对这个字段的序列化;</div><div style="">2)为此类型通过 ASM 字节码动态生成一个专属的 ObjectWriter 类进而加载并实例化,用于专门实现对这个类型对象的序列化写操作,通过这种方式避免了反射的低效性,而且 Fastjson 会缓存这些动态生成的 ObjectWriter 类,后续再序列化会很快;</div><div style="">3)使用 ObjectWriter 对每个字段进行序列化并追加到最终的序列化结果。</div></font>" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=top;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="280" y="10" width="800" height="90" as="geometry" />
</mxCell>
<mxCell id="LhijFJnAiS_UeM6sa_ox-1" value="<p style="margin: 4px 0px 0px; text-align: center;"><b>ObjectWriter&lt;T&gt;</b><br style="font-size: 11px;"></p><hr style="font-size: 11px;"><p style="margin: 0px 0px 0px 4px;"><font color="#007fff">// 读取输出格式控制</font></p><p style="margin: 0px 0px 0px 4px;">long getFeatures()<br></p><p style="margin: 0px 0px 0px 4px;"><font color="#007fff">// 读取字段序列化器</font></p><p style="margin: 0px 0px 0px 4px;">List&lt;FieldWriter&gt; getFieldWriters()<br></p><p style="margin: 0px 0px 0px 4px;">FieldWriter getFieldWriter(long hashCode)<br></p><p style="margin: 0px 0px 0px 4px;">Object getFieldValue(Object object, String fieldName)<br></p><p style="margin: 0px 0px 0px 4px;">FieldWriter getFieldWriter(String name)<br></p><p style="margin: 0px 0px 0px 4px;"><font color="#007fff">//</font></p><p style="margin: 0px 0px 0px 4px;">default boolean writeTypeInfo(JSONWriter jsonWriter)<br></p><p style="margin: 0px 0px 0px 4px;"><font color="#007fff">//一些序列化写方法</font></p><p style="margin: 0px 0px 0px 4px;">void writeJSONB(JSONWriter jsonWriter, Object object, Object fieldName, Type fieldType, long features)<br></p><p style="margin: 0px 0px 0px 4px;">void writeArrayMappingJSONB(JSONWriter jsonWriter, Object object)<br></p><p style="margin: 0px 0px 0px 4px;">void writeArrayMappingJSONB(JSONWriter jsonWriter, Object object, Object fieldName, Type fieldType, long features)<br></p><p style="margin: 0px 0px 0px 4px;">void writeArrayMapping(JSONWriter jsonWriter, Object object, Object fieldName, Type fieldType, long features)<br></p><p style="margin: 0px 0px 0px 4px;">void write(JSONWriter jsonWriter, Object object)<br></p><p style="margin: 0px 0px 0px 4px;">String toJSONString(T object, JSONWriter.Feature... features)<br></p><p style="margin: 0px 0px 0px 4px;">void write(JSONWriter jsonWriter, Object object, Object fieldName, Type fieldType, long features)<br></p><p style="margin: 0px 0px 0px 4px;"><font color="#007fff">// Filter 相关,Filter用于拓展序列化控制</font></p><p style="margin: 0px 0px 0px 4px;">boolean hasFilter(JSONWriter jsonWriter)<br></p><p style="margin: 0px 0px 0px 4px;">void setFilter(Filter filter)<br></p><p style="margin: 0px 0px 0px 4px;">default void writeWithFilter(JSONWriter jsonWriter, Object object)<br></p><p style="margin: 0px 0px 0px 4px;">...</p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=11;fontFamily=Helvetica;html=1;whiteSpace=wrap;fillColor=#d5e8d4;strokeColor=#82b366;" vertex="1" parent="1">
<mxGeometry x="-520" y="720" width="480" height="360" as="geometry" />
</mxCell>
<mxCell id="LhijFJnAiS_UeM6sa_ox-4" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;endArrow=block;endFill=1;" edge="1" parent="1" source="LhijFJnAiS_UeM6sa_ox-3" target="9sC5CoJF8o419bWHhUuv-8">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="LhijFJnAiS_UeM6sa_ox-3" value="<p style="margin: 4px 0px 0px; text-align: center;"><b>ObjectWriter1&lt;T&gt; -&nbsp;</b><b style="background-color: initial;">ObjectWriter12&lt;T&gt;&nbsp;</b></p><hr style="font-size: 11px;"><p style="margin: 0px 0px 0px 4px;"><font color="#007fff"><b>对某个类型的序列化器,数字代表参数个数,这么搞应该是为了提升性能,超过12个字段的类使用 ObjectWriterAdapter 写</b></font></p><p style="margin: 0px 0px 0px 4px;"><font color="#007fff"><br></font></p><p style="margin: 0px 0px 0px 4px;"><font color="#007fff">// 字段序列化器,ObjectWriter2 表示内部有两个字段序列化器</font></p><p style="margin: 0px 0px 0px 4px;">public final FieldWriter <b>fieldWriter0</b>;</p><p style="margin: 0px 0px 0px 4px;">public final FieldWriter <b>fieldWriter1</b>;</p><hr style="font-size: 11px;"><p style="margin: 0px 0px 0px 4px; font-size: 11px;"><br></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=11;fontFamily=Helvetica;html=1;whiteSpace=wrap;" vertex="1" parent="1">
<mxGeometry x="-520" y="1720" width="480" height="160" as="geometry" />
</mxCell>
<mxCell id="LhijFJnAiS_UeM6sa_ox-6" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;endArrow=block;endFill=1;" edge="1" parent="1" source="LhijFJnAiS_UeM6sa_ox-5" target="LhijFJnAiS_UeM6sa_ox-3">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="LhijFJnAiS_UeM6sa_ox-5" value="<p style="margin: 4px 0px 0px; text-align: center;"><b>OWG_1_2_User</b><br></p><hr style="font-size: 11px;"><p style="margin: 0px 0px 0px 4px;"><font color="#007fff"><b>自动生成的针对 User 类型的序列化器, 内部只是重写了序列化方法</b></font></p><hr style="font-size: 11px;"><p style="margin: 0px 0px 0px 4px; font-size: 11px;"><br></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=11;fontFamily=Helvetica;html=1;whiteSpace=wrap;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" vertex="1" parent="1">
<mxGeometry x="-520" y="1920" width="480" height="80" as="geometry" />
</mxCell>
<mxCell id="LhijFJnAiS_UeM6sa_ox-8" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;endArrow=block;endFill=1;" edge="1" parent="1" source="LhijFJnAiS_UeM6sa_ox-7" target="9sC5CoJF8o419bWHhUuv-9">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="LhijFJnAiS_UeM6sa_ox-7" value="<p style="margin: 4px 0px 0px; text-align: center;"><b>FieldWriterStringMethod</b></p><hr style="font-size: 11px;"><p style="margin: 0px 0px 0px 4px;"><font color="#007fff"><b>这个类表示这个字段序列化器是针对String类型字段,使用Getter方法读字段值</b></font></p><p style="margin: 0px 0px 0px 4px;"><font color="#007fff">内部仅仅重写了FieldWriter 方法,没有拓展字段</font></p><hr style="font-size: 11px;"><p style="margin: 0px 0px 0px 4px; font-size: 11px;"><br></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=11;fontFamily=Helvetica;html=1;whiteSpace=wrap;" vertex="1" parent="1">
<mxGeometry x="-1040" y="1280" width="480" height="80" as="geometry" />
</mxCell>
<mxCell id="LhijFJnAiS_UeM6sa_ox-11" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;endArrow=block;endFill=1;" edge="1" parent="1" source="LhijFJnAiS_UeM6sa_ox-10" target="9sC5CoJF8o419bWHhUuv-9">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="LhijFJnAiS_UeM6sa_ox-10" value="<p style="margin: 4px 0px 0px; text-align: center;"><b>FieldWriterStringFunc&lt;T&gt;</b><br></p><hr style="font-size: 11px;"><p style="margin: 0px 0px 0px 4px;"><font color="#007fff"><b>这个类表示这个字段序列化器是针对String类型字段,使用Function函数读字段值</b></font></p><p style="margin: 0px 0px 0px 4px;"><font color="#007fff"><b><br></b></font></p><p style="margin: 0px 0px 0px 4px;">final Function&lt;T, String&gt; function;</p><p style="margin: 0px 0px 0px 4px;">final boolean symbol;</p><p style="margin: 0px 0px 0px 4px;">final boolean trim;</p><p style="margin: 0px 0px 0px 4px;">final boolean raw;</p><hr style="font-size: 11px;"><p style="margin: 0px 0px 0px 4px; font-size: 11px;"><br></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=11;fontFamily=Helvetica;html=1;whiteSpace=wrap;" vertex="1" parent="1">
<mxGeometry x="-1480" y="1280" width="400" height="160" as="geometry" />
</mxCell>
<mxCell id="LhijFJnAiS_UeM6sa_ox-13" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;endArrow=block;endFill=1;" edge="1" parent="1" source="LhijFJnAiS_UeM6sa_ox-12" target="9sC5CoJF8o419bWHhUuv-9">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="LhijFJnAiS_UeM6sa_ox-12" value="<p style="margin: 4px 0px 0px; text-align: center;"><b>FieldWriterStringFiled&lt;T&gt;</b><br></p><hr style="font-size: 11px;"><p style="margin: 0px 0px 0px 4px;"><font color="#007fff"><b>这个类表示这个字段序列化器是针对String类型字段,使用Field对象反射读字段值或者通过 UNSAFE 读字段值</b></font></p><hr style="font-size: 11px;"><p style="margin: 0px 0px 0px 4px; font-size: 11px;"><br></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=11;fontFamily=Helvetica;html=1;whiteSpace=wrap;" vertex="1" parent="1">
<mxGeometry x="-1920" y="1280" width="400" height="80" as="geometry" />
</mxCell>
<mxCell id="LhijFJnAiS_UeM6sa_ox-20" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="LhijFJnAiS_UeM6sa_ox-14" target="LhijFJnAiS_UeM6sa_ox-19">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="LhijFJnAiS_UeM6sa_ox-14" value="<div style=""><div style=""><div><span style="background-color: initial;">public final void writeName3Raw(long name) { <font color="#007fff">// 这里3表示3个字符</font></span><br></div><div>&nbsp; &nbsp; int off = this.off;</div><div>&nbsp; &nbsp; int minCapacity = off + 10 + indent;</div><div>&nbsp; &nbsp; if (minCapacity &gt;= this.chars.length) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; ensureCapacity(minCapacity);</div><div>&nbsp; &nbsp; }</div><div><br></div><div>&nbsp; &nbsp; char[] chars = this.<b>chars</b>;</div><div>&nbsp; &nbsp; if (<b>startObject</b>) {&nbsp;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; startObject = false;</div><div>&nbsp; &nbsp; } else {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; chars[off++] = ',';</div><div>&nbsp; &nbsp; &nbsp; &nbsp; if (pretty) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; off = indent(chars, off, indent);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; }</div><div><font color="#007fff"><b>&nbsp; &nbsp; // 字节数组中off索引位置开始追加字段名的UTF-16编码</b></font></div><div>&nbsp; &nbsp; putLong(chars, off, name);</div><div>&nbsp; &nbsp; this.off = off + 6;<font color="#007fff"> //3个字符加上 "": 一共6个字符</font></div><div>}</div></div></div>" style="rounded=1;whiteSpace=wrap;html=1;align=left;fontSize=11;arcSize=3;" vertex="1" parent="1">
<mxGeometry x="1241" y="2280" width="439" height="280" as="geometry" />
</mxCell>
<mxCell id="LhijFJnAiS_UeM6sa_ox-17" value="<div style=""><font size="1" color="#007fff" style=""><b style="font-size: 11px;">由于内部涉及 ASM 自动生成代码,自动生成的代码无法进入单步调试,建议将生成的字节码输出到class文件反编译,将反编译的类贴到源码中进行调试,比如像下面这样测试</b></font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;"><br></font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">@Test</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">public void testDynamicObjectWriter() throws NoSuchMethodException {</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; User user = new User();</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; user.setUsername("Arvin");</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; user.setAge(18);</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;"><br></font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; ObjectWriterProvider provider = new ObjectWriterProvider();</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; JSONWriter writer = JSONWriter.of(new JSONWriter.Context(provider));</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; writer.rootObject = user;</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; writer.path = JSONWriter.Path.ROOT;</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;"><br></font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; Class objectClass = User.class;</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; BeanInfo beanInfo = new BeanInfo(provider);</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; provider.getBeanInfo(beanInfo, objectClass);</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; long beanFeatures = beanInfo.writerFeatures;</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; long writerFieldFeatures = beanFeatures;</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; List&lt;FieldWriter&gt; fieldWriters = new ArrayList&lt;&gt;();</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; Map&lt;String, FieldWriter&gt; fieldWriterMap = new LinkedHashMap&lt;&gt;();</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; final FieldInfo fieldInfo = new FieldInfo();</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; // 提取 public 字段并创建对应的 FiledWriter</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; BeanUtils.declaredFields(objectClass, field -&gt; {</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; fieldInfo.init();</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; fieldInfo.ignore = ((field.getModifiers() &amp; Modifier.PUBLIC) == 0 || (field.getModifiers() &amp; Modifier.TRANSIENT) != 0);</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; FieldWriter fieldWriter = ObjectWriterCreatorASM.INSTANCE.publicCreteFieldWriter(objectClass, writerFieldFeatures, provider, beanInfo, fieldInfo, field);</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; if (fieldWriter != null) {</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FieldWriter origin = fieldWriterMap.putIfAbsent(fieldWriter.fieldName, fieldWriter);</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (origin != null) {</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int cmp = origin.compareTo(fieldWriter);</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (cmp &gt; 0) {</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fieldWriterMap.put(fieldWriter.fieldName, fieldWriter);</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; }</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; });</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; // 提取有 getter 方法的字段并创建对应的 FiledWriter, 原实现比较复杂但是等效于下面代码</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; //BeanUtils.getters(objectClass, mixIn, beanInfo.kotlin, method -&gt; {</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; String[][] fieldsInfo = new String[][]{</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {"username", "getUsername"},</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {"age", "getAge"}</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; };</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; for (String[] strings : fieldsInfo) {</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; String fieldName = strings[0];</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; Method method = User.class.getMethod(strings[1]);</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; FieldWriter fieldWriter = ObjectWriterCreatorASM.INSTANCE.publicCreateFieldWriter(</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; provider, objectClass, fieldName,</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fieldInfo.ordinal,</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fieldInfo.features,</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fieldInfo.format,</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fieldInfo.locale,</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fieldInfo.label,</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; method,</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; null //writeUsingWriter</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; );</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; FieldWriter origin = fieldWriterMap.putIfAbsent(fieldName, fieldWriter);</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; if (origin != null &amp;&amp; origin.compareTo(fieldWriter) &gt; 0) {</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fieldWriterMap.put(fieldName, fieldWriter);</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; &nbsp; &nbsp; }</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; }</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; //});</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; fieldWriters.addAll(fieldWriterMap.values());</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;"><br></font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; OWG_1_2_User objectWriter = new OWG_1_2_User(User.class, beanInfo.typeKey, beanInfo.typeName, writerFieldFeatures, fieldWriters);</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; objectWriter.write(writer, user, null, null, 0);</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; String result = writer.toString();</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; System.out.println(result);</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">}</font></div>" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
<mxGeometry x="40" y="560" width="600" height="880" as="geometry" />
</mxCell>
<mxCell id="LhijFJnAiS_UeM6sa_ox-18" value="JSONWriterUTF16" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="1400.5" y="2250" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="LhijFJnAiS_UeM6sa_ox-19" value="<div style=""><div style=""><div><font color="#007fff">// 由于 name 是 各字符ASCII码16进制连起来得到的,而 UTF-16对 ASCII 每个字符要求占占两个字节,所以里面需要补0</font></div><div><font color="#007fff">// 比如&nbsp;</font><font color="#007fff">3a2265676122 (:"ega") <b>经过下面转 UTF-16编码</b>是 003a00220065006700610022, 一共12Byte 需要通过 putLong 写两次(一次最多写8Byte)</font></div><div>private static void putLong(char[] chars, int off, long name) {</div><div><font color="#007fff">&nbsp; &nbsp; // 数组对象头部长:16, 已写入UTF-16字符编码长&nbsp; off &lt;&lt; 1</font></div><div>&nbsp; &nbsp; final long base = ARRAY_CHAR_BASE_OFFSET + (off &lt;&lt; 1);</div><div>&nbsp; &nbsp; UNSAFE.putLong(chars, base,</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (name &amp; 0xFFL)</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | ((name &amp; 0xFF00L) &lt;&lt; 8)</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | ((name &amp; 0xFF_0000L) &lt;&lt; 16)</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | ((name &amp; 0xFF00_0000L) &lt;&lt; 24));</div><div>&nbsp; &nbsp; UNSAFE.putLong(chars, base + 8,</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ((name &amp; 0xFF_0000_0000L) &gt;&gt; 32)</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | ((name &amp; 0xFF00_0000_0000L) &gt;&gt; 24)</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | ((name &amp; 0xFF_0000_0000_0000L) &gt;&gt; 16)</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | ((name &amp; 0xFF00_0000_0000_0000L) &gt;&gt; 8));</div><div>}</div></div></div>" style="rounded=1;whiteSpace=wrap;html=1;align=left;fontSize=11;arcSize=3;" vertex="1" parent="1">
<mxGeometry x="1721" y="2280" width="439" height="280" as="geometry" />
</mxCell>
<mxCell id="LhijFJnAiS_UeM6sa_ox-21" value="<font color="#007fff">63919404572962L 16进制数是&nbsp;3a2265676122&nbsp;<br>即 :"ega",即每个字符占1byte 连起来</font>" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="1241" y="2760" width="270" height="40" as="geometry" />
</mxCell>
<mxCell id="LhijFJnAiS_UeM6sa_ox-22" value="<p style="margin: 4px 0px 0px; text-align: center;">ObjectWriterCreator</p><hr style="font-size: 11px;"><p style="margin: 0px 0px 0px 4px; font-size: 11px;"><span style="background-color: initial;">public static final ObjectWriterCreator INSTANCE = new ObjectWriterCreator();</span><br></p><p style="margin: 0px 0px 0px 4px;">static final Map&lt;Class, LambdaInfo&gt; lambdaMapping = new HashMap&lt;&gt;();</p><p style="margin: 0px 0px 0px 4px;">protected final AtomicInteger jitErrorCount = new AtomicInteger();</p><p style="margin: 0px 0px 0px 4px;">protected volatile Throwable jitErrorLast;</p><hr style="font-size: 11px;"><p style="margin: 0px 0px 0px 4px; font-size: 11px;"><br></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=11;fontFamily=Helvetica;html=1;whiteSpace=wrap;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
<mxGeometry x="-1920" y="840" width="400" height="120" as="geometry" />
</mxCell>
<mxCell id="LhijFJnAiS_UeM6sa_ox-25" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;endArrow=block;endFill=1;" edge="1" parent="1" source="LhijFJnAiS_UeM6sa_ox-23" target="LhijFJnAiS_UeM6sa_ox-22">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="LhijFJnAiS_UeM6sa_ox-23" value="<p style="margin: 4px 0px 0px; text-align: center;"><b>ObjectWriterCreatorASM</b></p><hr style="font-size: 11px;"><p style="margin: 0px 0px 0px 4px;">public static final ObjectWriterCreatorASM INSTANCE = new ObjectWriterCreatorASM(</p><p style="margin: 0px 0px 0px 4px;">&nbsp; &nbsp; &nbsp; &nbsp; DynamicClassLoader.getInstance()</p><p style="margin: 0px 0px 0px 4px;">);</p><p style="margin: 0px 0px 0px 4px;">protected static final AtomicLong seed = new AtomicLong();</p><p style="margin: 0px 0px 0px 4px;">protected final DynamicClassLoader classLoader;</p><p style="margin: 0px 0px 0px 4px;">static final String[] INTERFACES = {TYPE_OBJECT_WRITER};</p><hr style="font-size: 11px;"><p style="margin: 0px 0px 0px 4px; font-size: 11px;"><br></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=11;fontFamily=Helvetica;html=1;whiteSpace=wrap;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
<mxGeometry x="-1920" y="1000" width="400" height="160" as="geometry" />
</mxCell>
<mxCell id="LhijFJnAiS_UeM6sa_ox-26" value="ObjectWriterProvider" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="915" y="370" width="130" height="30" as="geometry" />
</mxCell>
<mxCell id="LhijFJnAiS_UeM6sa_ox-30" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;dashed=1;" edge="1" parent="1" source="LhijFJnAiS_UeM6sa_ox-27">
<mxGeometry relative="1" as="geometry">
<mxPoint x="760" y="3349.666666666666" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="LhijFJnAiS_UeM6sa_ox-27" value="User user = JSON.parseObject(json, User.class);<br><font color="#007fff"><b>反序列化</b></font>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontSize=11;" vertex="1" parent="1">
<mxGeometry x="40" y="3320" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="LhijFJnAiS_UeM6sa_ox-28" value="<font style="font-size: 10px;" color="#007fff">反序列化的数据结构实现和序列化过程是一致的,流程相反的<br><span style="">包含 JSONReader ObjectReader ObjectReaderProvider <br>ObjectReaderCreatorASM 等核心类</span><br></font>" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="40" y="3390" width="290" height="60" as="geometry" />
</mxCell>
<mxCell id="LhijFJnAiS_UeM6sa_ox-29" value="<div style=""><div style=""><div style="font-size: 10px;"><font color="#007fff"><b>//这是测试中 Fastjson2 针对 User 类型动态生成的 ObjectReader 类型</b></font></div><div style=""><div style="">public final class ORG_1_2_User extends ObjectReader2 {</div><div style="">&nbsp; &nbsp; public ORG_1_2_User(Class var1, Supplier var2, FieldReader[] var3) {</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; super(var1, (String)null, (String)null, 0L, (JSONSchema)null, var2, (Function)null, var3);</div><div style="">&nbsp; &nbsp; }</div><div style=""><br></div><div style="">&nbsp; &nbsp; public Object createInstance(long var1) {</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; return new User();</div><div style="">&nbsp; &nbsp; }</div><div style=""><br></div><div style="">&nbsp; &nbsp; public Object readJSONBObject(JSONReader var1, Type var2, Object var3, long var4) {</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; ...</div><div style="">&nbsp; &nbsp; }</div><div style=""><br></div><div style="">&nbsp; &nbsp; public Object readArrayMappingJSONBObject(JSONReader var1, Type var2, Object var3, long var4) {</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; ...</div><div style="">&nbsp; &nbsp; }</div><div style=""><br></div><div style="">&nbsp; &nbsp; public Object <b>readObject</b>(JSONReader <b>var1</b>, Type var2, Object var3, long var4) {</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; if (var1.jsonb) {</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return this.readJSONBObject(var1, var2, var3, var4);</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; } else {</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; User var6;</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (var1.<b>isArray</b>()) {</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (var1.isSupportBeanArray(var4)) {</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var1.nextIfArrayStart();</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; User var10 = new User();</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (var1.isInitStringFieldAsEmpty()) {</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.initStringFieldAsEmpty(var10);</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div style=""><br></div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var6 = var10;</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var6.setAge(var1.readInt32());</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String var10003 = var1.readString();</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (var10003 != null) {</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div style=""><br></div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var6.setUsername(var10003);</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var1.nextIfArrayEnd();</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var1.nextIfComma();</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return var6;</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } else {</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return this.processObjectInputSingleItemArray(var1, var2, var3, var4);</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } else {</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (!var1.nextIfObjectStart() &amp;&amp; var1.nextIfNullOrEmptyString()) {</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var6 = null;</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } else {</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; User <b>var10001</b> = new User();</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (var1.isInitStringFieldAsEmpty()) {</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.initStringFieldAsEmpty(var10001);</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div style=""><br></div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var6 = var10001;</div><div style=""><br></div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for(int var7 = 0; !var1.nextIfObjectEnd(); ++var7) {</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; switch (var1.<b>getRawInt</b>()) {&nbsp; <font color="#007fff">// 读取4个字符,内部通过UNSAFE 读 getLong 读8个字节, 由于英文每个字符UTF-16编码占两个字节,所以实际读取了4个字符</font></div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case 1701273890:<font color="#007fff">&nbsp; // 实际是 ega" 的ASCII编码的10进制</font></div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (var1.nextIfName4Match3()) {</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var6.<b>setAge</b>(var1.readInt32());</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; continue;</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case 1702065442:<font color="#007fff">&nbsp;// 实际是 esu" 的ASCII编码的10进制</font></div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (var1.nextIfName4Match8(1835101810, (byte)101)) {</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String var10002 = var1.readString();</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (var10002 != null) {</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var6.<b>setUsername</b>(var10002);</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; continue;</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div style=""><br></div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; long var8;</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if ((var8 = var1.readFieldNameHashCode()) == -1L) {</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div style=""><br></div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (var7 == 0 &amp;&amp; var8 == 435678704704L &amp;&amp; var1.isSupportAutoTypeOrHandler(var4)) {</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return this.<b>autoType</b>(var1, this.objectClass, var4);</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div style=""><br></div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.<b>readFieldValue</b>(var8, var1, var4, var6);</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div style=""><br></div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var1.nextIfComma();</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return var6;</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; }</div><div style="">&nbsp; &nbsp; }</div><div style=""><br></div><div style="">&nbsp; &nbsp; public FieldReader getFieldReader(long var1) {</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; ...</div><div style="">&nbsp; &nbsp; }</div><div style=""><br></div><div style="">&nbsp; &nbsp; public FieldReader getFieldReaderLCase(long var1) {</div><div style="">&nbsp; &nbsp; &nbsp; &nbsp; ...</div><div style="">&nbsp; &nbsp; }</div><div style="">}</div><div style="font-size: 10px;"><br></div></div></div></div>" style="rounded=1;whiteSpace=wrap;html=1;align=left;fontSize=10;arcSize=1;fillColor=#f5f5f5;fontColor=#333333;strokeColor=#666666;" vertex="1" parent="1">
<mxGeometry x="761" y="3320" width="439" height="1280" as="geometry" />
</mxCell>
<mxCell id="LhijFJnAiS_UeM6sa_ox-31" value="反序列化时 AutoType 原理<br>与安全问题分析<br><font color="#007fff">TODO</font>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontSize=11;" vertex="1" parent="1">
<mxGeometry x="40" y="4640" width="200" height="60" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>