protected void checkIncorrectObject(T object) { if (object != null && !(object instanceof Serializable)) { String className = Util.className(object.getClass()); throw new IllegalArgumentException(String.format("Class is not registered: %s\nNote: To register this class use: kryo.register(\"%s\".class);", className, className)); } }
protected void checkIncorrectClass(Class type) { if (type != null && !Serializable.class.isAssignableFrom(type)) { throw new IllegalArgumentException(String.format("Class is not registered: %s\nNote: To register this class use: kryo.register(\"%s\".class);", Util.className(type), Util.className(type))); } }
final private void writeLittleEndianInt (int val) { if (isLittleEndian) writeInt(val); else writeInt(Util.swapInt(val)); }
final private void writeLittleEndianLong (long val) { if (isLittleEndian) writeLong(val); else writeLong(Util.swapLong(val)); }
@Override public boolean useReferences(Class type) { return !Util.isWrapperClass(type); }
/** Called when the list of cached fields must be rebuilt. This is done any time settings are changed that affect which fields * will be used. It is called from the constructor for FieldSerializer, but not for subclasses. Subclasses must call this from * their constructor. */ protected void rebuildCachedFields () { if (TRACE && generics != null) trace("kryo", "generic type parameters are: " + Arrays.toString(generics)); if (type.isInterface()) { fields = new CachedField[0]; // No fields to serialize. return; } hasObjectFields = false; // For generic classes, generate a mapping from type variable names to the concrete types // This mapping is the same for the whole class. Generics genScope = buildGenericsScope(type, generics); genericsScope = genScope; // Push proper scopes at serializer construction time if (genericsScope != null) kryo.pushGenericsScope(type, genericsScope); // Collect all fields. List<Field> allFields = new ArrayList(); Class nextClass = type; while (nextClass != Object.class) { Field[] declaredFields = nextClass.getDeclaredFields(); if (declaredFields != null) { for (Field f : declaredFields) { if (Modifier.isStatic(f.getModifiers())) continue; allFields.add(f); } } nextClass = nextClass.getSuperclass(); } ObjectMap context = kryo.getContext(); IntArray useAsm = new IntArray(); // Sort fields by their offsets if (useMemRegions && !useAsmEnabled && unsafe() != null) { Field[] allFieldsArray = softFieldsByOffset(allFields); allFields = Arrays.asList(allFieldsArray); } // TODO: useAsm is modified as a side effect, this should be pulled out of buildValidFields List<Field> validFields = buildValidFields(false, allFields, context, useAsm); List<Field> validTransientFields = buildValidFields(true, allFields, context, useAsm); // Use ReflectASM for any public fields. if (useAsmEnabled && !Util.isAndroid && Modifier.isPublic(type.getModifiers()) && useAsm.indexOf(1) != -1) { try { access = FieldAccess.get(type); } catch (RuntimeException ignored) { } } List<CachedField> cachedFields = new ArrayList(validFields.size()); List<CachedField> cachedTransientFields = new ArrayList(validTransientFields.size()); createCachedFields(useAsm, validFields, cachedFields, 0); createCachedFields(useAsm, validTransientFields, cachedTransientFields, validFields.size()); Collections.sort(cachedFields, this); fields = cachedFields.toArray(new CachedField[cachedFields.size()]); Collections.sort(cachedTransientFields, this); transientFields = cachedTransientFields.toArray(new CachedField[cachedTransientFields.size()]); initializeCachedFields(); if (genericsScope != null) kryo.popGenericsScope(); }
/** Returns true if the specified type is final. Final types can be serialized more efficiently because they are * non-polymorphic. * <p> * This can be overridden to force non-final classes to be treated as final. Eg, if an application uses ArrayList extensively * but never uses an ArrayList subclass, treating ArrayList as final could allow FieldSerializer to save 1-2 bytes per * ArrayList field. */ public boolean isFinal (Class type) { if (type == null) throw new IllegalArgumentException("type cannot be null."); if (type.isArray()) return Modifier.isFinal(Util.getElementClass(type).getModifiers()); return Modifier.isFinal(type.getModifiers()); }