@SuppressWarnings("unchecked")
    @Override
    public <T> T readObject(ByteBuffer data, Class<T> c) throws IOException {
    
        // Read the null/non-null marker
        if (data.get() == 0x0)
            return null;
    
        SavedField[] fields = savedFields.get(c);

        T object;
        try {
            Constructor<T> ctor = savedCtors.get(c);
            object = ctor.newInstance();
        } catch (Exception e) {
            throw new SerializerException( "Error creating object of type:" + c, e );
        }

        for (SavedField savedField : fields) {
            Field field = savedField.field;
            Serializer serializer = savedField.serializer;
            if( log.isLoggable(Level.FINER) ) {
                log.log(Level.FINER, "Reading field:{0} using serializer:{1}", new Object[]{field, serializer});
            }
            Object value;

            if (serializer != null) {
                value = serializer.readObject(data, field.getType());
            } else {
                value = Serializer.readClassAndObject(data);
            }
            try {
                field.set(object, value);
            } catch (IllegalAccessException e) {
                throw new SerializerException( "Error reading object", e);
            }
        }
        return object;
    }
The field serializer is the default serializer used for custom class.

@author Lars Wesselius, Nathan Sweet
jme3-networking/src/main/java/com/jme3/network/serializing/serializers/FieldSerializer.java