64
64
* @author Nathan Sweet <[email protected] >
65
65
* @author Roman Levenstein <[email protected] > */
66
66
public class FieldSerializer <T > extends Serializer <T > implements Comparator <FieldSerializer .CachedField > {
67
+
67
68
final Kryo kryo ;
68
69
final Class type ;
69
70
/** type variables declared for this type */
70
71
final TypeVariable [] typeParameters ;
71
72
final Class componentType ;
73
+ private final FieldSerializerConfig config ;
72
74
private CachedField [] fields = new CachedField [0 ];
73
75
private CachedField [] transientFields = new CachedField [0 ];
74
76
protected HashSet <CachedField > removedFields = new HashSet ();
75
77
Object access ;
76
- private boolean fieldsCanBeNull = true , setFieldsAsAccessible = true ;
77
- private boolean ignoreSyntheticFields = true ;
78
- private boolean fixedFieldTypes ;
79
- /** If set, ASM-backend is used. Otherwise Unsafe-based backend or reflection is used */
80
- private boolean useAsmEnabled ;
81
78
private FieldSerializerUnsafeUtil unsafeUtil ;
82
79
83
80
private FieldSerializerGenericsUtil genericsUtil ;
@@ -101,9 +98,6 @@ public class FieldSerializer<T> extends Serializer<T> implements Comparator<Fiel
101
98
* </p> */
102
99
private boolean useMemRegions = false ;
103
100
104
- /** If set, transient fields will be copied */
105
- private boolean copyTransient = true ;
106
-
107
101
/** If set, transient fields will be serialized */
108
102
private final boolean serializeTransient = false ;
109
103
@@ -130,29 +124,12 @@ public class FieldSerializer<T> extends Serializer<T> implements Comparator<Fiel
130
124
}
131
125
132
126
{
133
- useAsmEnabled = !unsafeAvailable ;
134
127
varIntsEnabled = true ;
135
128
if (TRACE ) trace ("kryo" , "Optimize ints: " + varIntsEnabled );
136
129
}
137
130
138
131
public FieldSerializer (Kryo kryo , Class type ) {
139
- this .kryo = kryo ;
140
- this .type = type ;
141
- this .typeParameters = type .getTypeParameters ();
142
- if (this .typeParameters == null || this .typeParameters .length == 0 )
143
- this .componentType = type .getComponentType ();
144
- else
145
- this .componentType = null ;
146
- this .useAsmEnabled = kryo .getAsmEnabled ();
147
- if (!this .useAsmEnabled && !unsafeAvailable ) {
148
- this .useAsmEnabled = true ;
149
- if (TRACE ) trace ("kryo" , "sun.misc.Unsafe is unavailable, using ASM." );
150
- }
151
- this .genericsUtil = new FieldSerializerGenericsUtil (this );
152
- this .unsafeUtil = FieldSerializerUnsafeUtil .Factory .getInstance (this );
153
- this .annotationsUtil = new FieldSerializerAnnotationsUtil (this );
154
- this .copyTransient = kryo .getCopyTransient ();
155
- rebuildCachedFields ();
132
+ this (kryo , type , null );
156
133
}
157
134
158
135
public FieldSerializer (Kryo kryo , Class type , Class [] generics ) {
@@ -164,15 +141,10 @@ public FieldSerializer (Kryo kryo, Class type, Class[] generics) {
164
141
this .componentType = type .getComponentType ();
165
142
else
166
143
this .componentType = null ;
167
- this .useAsmEnabled = kryo .getAsmEnabled ();
168
- if (!this .useAsmEnabled && !unsafeAvailable ) {
169
- this .useAsmEnabled = true ;
170
- if (TRACE ) trace ("kryo" , "sun.misc.Unsafe is unavailable, using ASM." );
171
- }
144
+ this .config = kryo .getFieldSerializerConfig ().clone ();
172
145
this .genericsUtil = new FieldSerializerGenericsUtil (this );
173
146
this .unsafeUtil = FieldSerializerUnsafeUtil .Factory .getInstance (this );
174
147
this .annotationsUtil = new FieldSerializerAnnotationsUtil (this );
175
- this .copyTransient = kryo .getCopyTransient ();
176
148
rebuildCachedFields ();
177
149
}
178
150
@@ -226,7 +198,7 @@ protected void rebuildCachedFields (boolean minorRebuild) {
226
198
ObjectMap context = kryo .getContext ();
227
199
228
200
// Sort fields by their offsets
229
- if (useMemRegions && !useAsmEnabled && unsafeAvailable ) {
201
+ if (useMemRegions && !config . isUseAsm () && unsafeAvailable ) {
230
202
try {
231
203
Field [] allFieldsArray = (Field [])sortFieldsByOffsetMethod .invoke (null , allFields );
232
204
allFields = Arrays .asList (allFieldsArray );
@@ -242,7 +214,7 @@ protected void rebuildCachedFields (boolean minorRebuild) {
242
214
validTransientFields = buildValidFields (true , allFields , context , useAsm );
243
215
244
216
// Use ReflectASM for any public fields.
245
- if (useAsmEnabled && !Util .isAndroid && Modifier .isPublic (type .getModifiers ()) && useAsm .indexOf (1 ) != -1 ) {
217
+ if (config . isUseAsm () && !Util .isAndroid && Modifier .isPublic (type .getModifiers ()) && useAsm .indexOf (1 ) != -1 ) {
246
218
try {
247
219
access = FieldAccess .get (type );
248
220
} catch (RuntimeException ignored ) {
@@ -299,10 +271,10 @@ private List<Field> buildValidFields (boolean transientFields, List<Field> allFi
299
271
int modifiers = field .getModifiers ();
300
272
if (Modifier .isTransient (modifiers ) != transientFields ) continue ;
301
273
if (Modifier .isStatic (modifiers )) continue ;
302
- if (field .isSynthetic () && ignoreSyntheticFields ) continue ;
274
+ if (field .isSynthetic () && config . isIgnoreSyntheticFields () ) continue ;
303
275
304
276
if (!field .isAccessible ()) {
305
- if (!setFieldsAsAccessible ) continue ;
277
+ if (!config . isSetFieldsAsAccessible () ) continue ;
306
278
try {
307
279
field .setAccessible (true );
308
280
} catch (AccessControlException ex ) {
@@ -324,7 +296,7 @@ private List<Field> buildValidFields (boolean transientFields, List<Field> allFi
324
296
325
297
private void createCachedFields (IntArray useAsm , List <Field > validFields , List <CachedField > cachedFields , int baseIndex ) {
326
298
327
- if (useAsmEnabled || !useMemRegions ) {
299
+ if (config . isUseAsm () || !useMemRegions ) {
328
300
for (int i = 0 , n = validFields .size (); i < n ; i ++) {
329
301
Field field = validFields .get (i );
330
302
int accessIndex = -1 ;
@@ -376,16 +348,16 @@ CachedField newCachedField (Field field, int fieldIndex, int accessIndex) {
376
348
cachedField .field = field ;
377
349
cachedField .varIntsEnabled = varIntsEnabled ;
378
350
379
- if (!useAsmEnabled ) {
351
+ if (!config . isUseAsm () ) {
380
352
cachedField .offset = unsafeUtil .getObjectFieldOffset (field );
381
353
}
382
354
383
355
cachedField .access = (FieldAccess )access ;
384
356
cachedField .accessIndex = accessIndex ;
385
- cachedField .canBeNull = fieldsCanBeNull && !fieldClass [0 ].isPrimitive () && !field .isAnnotationPresent (NotNull .class );
357
+ cachedField .canBeNull = config . isFieldsCanBeNull () && !fieldClass [0 ].isPrimitive () && !field .isAnnotationPresent (NotNull .class );
386
358
387
359
// Always use the same serializer for this field if the field's class is final.
388
- if (kryo .isFinal (fieldClass [0 ]) || fixedFieldTypes ) cachedField .valueClass = fieldClass [0 ];
360
+ if (kryo .isFinal (fieldClass [0 ]) || config . isFixedFieldTypes () ) cachedField .valueClass = fieldClass [0 ];
389
361
390
362
return cachedField ;
391
363
}
@@ -395,7 +367,7 @@ CachedField newMatchingCachedField (Field field, int accessIndex, Class fieldCla
395
367
CachedField cachedField ;
396
368
if (accessIndex != -1 ) {
397
369
cachedField = getAsmFieldFactory ().createCachedField (fieldClass , field , this );
398
- } else if (!useAsmEnabled ) {
370
+ } else if (!config . isUseAsm () ) {
399
371
cachedField = getUnsafeFieldFactory ().createCachedField (fieldClass , field , this );
400
372
} else {
401
373
cachedField = getObjectFieldFactory ().createCachedField (fieldClass , field , this );
@@ -444,8 +416,7 @@ public int compare (CachedField o1, CachedField o2) {
444
416
* cached fields}.
445
417
* @param fieldsCanBeNull False if none of the fields are null. Saves 0-1 byte per field. True if it is not known (default). */
446
418
public void setFieldsCanBeNull (boolean fieldsCanBeNull ) {
447
- this .fieldsCanBeNull = fieldsCanBeNull ;
448
- if (TRACE ) trace ("kryo" , "setFieldsCanBeNull: " + fieldsCanBeNull );
419
+ config .setFieldsCanBeNull (fieldsCanBeNull );
449
420
rebuildCachedFields ();
450
421
}
451
422
@@ -454,45 +425,36 @@ public void setFieldsCanBeNull (boolean fieldsCanBeNull) {
454
425
* {@link Field#setAccessible(boolean) set as accessible} if necessary (default). If false, only fields in the public
455
426
* API will be serialized. */
456
427
public void setFieldsAsAccessible (boolean setFieldsAsAccessible ) {
457
- this .setFieldsAsAccessible = setFieldsAsAccessible ;
458
- if (TRACE ) trace ("kryo" , "setFieldsAsAccessible: " + setFieldsAsAccessible );
428
+ config .setFieldsAsAccessible (setFieldsAsAccessible );
459
429
rebuildCachedFields ();
460
430
}
461
431
462
432
/** Controls if synthetic fields are serialized. Default is true. Calling this method resets the {@link #getFields() cached
463
433
* fields}.
464
434
* @param ignoreSyntheticFields If true, only non-synthetic fields will be serialized. */
465
435
public void setIgnoreSyntheticFields (boolean ignoreSyntheticFields ) {
466
- this .ignoreSyntheticFields = ignoreSyntheticFields ;
467
- if (TRACE ) trace ("kryo" , "setIgnoreSyntheticFields: " + ignoreSyntheticFields );
436
+ config .setIgnoreSyntheticFields (ignoreSyntheticFields );
468
437
rebuildCachedFields ();
469
438
}
470
439
471
440
/** Sets the default value for {@link CachedField#setClass(Class)} to the field's declared type. This allows FieldSerializer to
472
441
* be more efficient, since it knows field values will not be a subclass of their declared type. Default is false. Calling this
473
442
* method resets the {@link #getFields() cached fields}. */
474
443
public void setFixedFieldTypes (boolean fixedFieldTypes ) {
475
- this .fixedFieldTypes = fixedFieldTypes ;
476
- if (TRACE ) trace ("kryo" , "setFixedFieldTypes: " + fixedFieldTypes );
444
+ config .setFixedFieldTypes (fixedFieldTypes );
477
445
rebuildCachedFields ();
478
446
}
479
447
480
448
/** Controls whether ASM should be used. Calling this method resets the {@link #getFields() cached fields}.
481
449
* @param setUseAsm If true, ASM will be used for fast serialization. If false, Unsafe will be used (default) */
482
450
public void setUseAsm (boolean setUseAsm ) {
483
- useAsmEnabled = setUseAsm ;
484
- if (!useAsmEnabled && !unsafeAvailable ) {
485
- useAsmEnabled = true ;
486
- if (TRACE ) trace ("kryo" , "sun.misc.Unsafe is unavailable, using ASM." );
487
- }
488
- // optimizeInts = useAsmBackend;
489
- if (TRACE ) trace ("kryo" , "setUseAsm: " + setUseAsm );
451
+ config .setUseAsm (setUseAsm );
490
452
rebuildCachedFields ();
491
453
}
492
454
493
455
// Enable/disable copying of transient fields
494
456
public void setCopyTransient (boolean setCopyTransient ) {
495
- copyTransient = setCopyTransient ;
457
+ config . setCopyTransient ( setCopyTransient ) ;
496
458
}
497
459
498
460
/** This method can be called for different fields having the same type. Even though the raw type is the same, if the type is
@@ -649,15 +611,15 @@ public Kryo getKryo () {
649
611
}
650
612
651
613
public boolean getUseAsmEnabled () {
652
- return useAsmEnabled ;
614
+ return config . isUseAsm () ;
653
615
}
654
616
655
617
public boolean getUseMemRegions () {
656
618
return useMemRegions ;
657
619
}
658
620
659
621
public boolean getCopyTransient () {
660
- return copyTransient ;
622
+ return config . isCopyTransient () ;
661
623
}
662
624
663
625
/** Used by {@link #copy(Kryo, Object)} to create the new object. This can be overridden to customize object creation, eg to
@@ -671,7 +633,7 @@ public T copy (Kryo kryo, T original) {
671
633
kryo .reference (copy );
672
634
673
635
// Copy transient fields
674
- if (copyTransient ) {
636
+ if (config . isCopyTransient () ) {
675
637
for (int i = 0 , n = transientFields .length ; i < n ; i ++)
676
638
transientFields [i ].copy (original , copy );
677
639
}
0 commit comments