https://github.com/alibaba/fastjson/issues/3693
上面的 #3639 提出了一个bug,即通过@JSONField#deserializeUsing属性指定的自定义反序列化器被后续的代码覆盖,并在1.2.76中进行了修复,然而我们在使用升级后的1.2.76时发现1.2.75中没有问题的代码出现报错,经定位是该Issue的解决方案引入了新的Bug。
我们的代码是构造了一个ClassA<ClassB<String>>这种样式的类,ClassA<T>的声明中有一个字段T data,实际类型是ClassB<String>,现在1.2.76的修复方案,虽然确保了@JSONField#deserializeUsing属性指定的自定义反序列化器具有最高的优先级,但是在我们的场景下,并没有使用@JSONField注解,原本ClassA中T data字段的反序列化器应该是针对运行时实际类型ClassB<String>创建的,现在却获取到的是一个普通的Object的通用反序列化器。
具体代码如下,1.2.76中:
    public ObjectDeserializer getFieldValueDeserilizer(ParserConfig config) {
        if (fieldValueDeserilizer == null) {
            JSONField annotation = fieldInfo.getAnnotation();
            if (annotation != null && annotation.deserializeUsing() != Void.class) {
                Class<?> deserializeUsing = annotation.deserializeUsing();
                try {
                    fieldValueDeserilizer = (ObjectDeserializer) deserializeUsing.newInstance();
                } catch (Exception ex) {
                    throw new JSONException("create deserializeUsing ObjectDeserializer error", ex);
                }
            } else {
                fieldValueDeserilizer = config.getDeserializer(fieldInfo.fieldClass, fieldInfo.fieldType);
            }
        }
        return fieldValueDeserilizer; // 这个成员变量和返回值不为空
    }这个方法无论成员变量fieldValueDeserilizer初始的状态是否为null,该方法执行后,成员变量fieldValueDeserilizer都会被转为非null的值,考虑了通过@JSONField注解自定义反序列化器的场景。
但是在下面的方法中:
@Override
    public void parseField(DefaultJSONParser parser, Object object, Type objectType, Map<String, Object> fieldValues) {
        if (this.fieldValueDeserilizer == null) {
            getFieldValueDeserilizer(parser.getConfig());
        }
        ObjectDeserializer fieldValueDeserilizer = this.fieldValueDeserilizer;
        Type fieldType = fieldInfo.fieldType;
        if (objectType instanceof ParameterizedType) {
            ParseContext objContext = parser.getContext();
            if (objContext != null) {
                objContext.type = objectType;
            }
            if (fieldType != objectType) {
                fieldType = FieldInfo.getFieldType(this.clazz, objectType, fieldType);
                if (fieldValueDeserilizer == null) { // 该处修改导致下面一行失效
                    fieldValueDeserilizer = parser.getConfig().getDeserializer(fieldType); // 代码失效,原有逻辑无法正确执行
                }
            }
        }1.2.76中的67行进行了一个null判断,但是ObjectDeserializer fieldValueDeserilizer = this.fieldValueDeserilizer即局部变量fieldValueDeserilizer正是成员变量this.fieldValueDeserilizer,而后者如上面所说的,在该方法调用上面的getFieldValueDeserilizer之后永远不会为null,所以导致68行代码不会被执行,而之前的版本能够处理这种嵌套的场景,原因就在于68行获取了一个与实际运行时类型匹配的反序列化器,现在这样的修复方案使得68行代码失效了,从而嵌套泛型的场景下失效,将给现有生产代码造成巨大影响