jackson Java lambda使用外部函数参数的TypeReference泛型类型抛出空异常

jtoj6r0c  于 2023-04-30  发布在  Java
关注(0)|答案(1)|浏览(127)

当我在lambda函数中使用new TypeReference<T>() {}并且T来自外部函数泛型参数时,它会抛出null异常。但是当这个语句直接写在函数中时就可以了。

  • Java版本:8
  • Jackson版本:2.12.5

有最小的可运行代码示例。
这将得到java.lang.IllegalArgumentException: Unrecognized Type: [null]

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.function.Function;

public class Main {

    public static void main(String[] args) {
        String test = "[\"test\"]";

        List<String> strings = getObjectConfig(test, new ArrayList<>());
        System.out.println(strings);
    }

    public static <T> T getObjectConfig(String key, T defaultValue) {
        return getCommon(
                key,
                v -> {
                    if (Objects.isNull(v)) {
                        return defaultValue;
                    } else {
                        try {
                            return new ObjectMapper().readValue(v, new TypeReference<T>() {});
                        } catch (JsonProcessingException e) {
                            throw new RuntimeException(e);
                        }
                    }
                }
        );
    }

    private static <T> T getCommon(String key, Function<String, T> transFunc) {
        try {
            String value = key;
            return transFunc.apply(value);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

但这没关系。

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

import java.util.ArrayList;
import java.util.List;

public class Main {

    public static void main(String[] args) throws Exception {
        String test = "[\"test\"]";

        List<String> strings = getObjectConfig(test, new ArrayList<>());
        System.out.println(strings);
    }

    private static <T> T getObjectConfig(String key, T defaultValue) throws JsonProcessingException {
        return new ObjectMapper().readValue(key, new TypeReference<T>() {});
    }

}
vsnjm48y

vsnjm48y1#

经过几次测试,我能够用Java 11重现你的bug。请注意,一切都与Java 17正常工作。
首先,我发现this post是关于一个类似的问题。
然后,为了解决这个问题,我专门通过了我遵循的类:

public static void main(String[] args) {
    String test = "[\"test\"]";

    List<String> strings = getObjectConfig(test, new ArrayList<String>(), ArrayList.class);
    System.out.println(strings);
}

public static <T> T getObjectConfig(String key, T defaultValue, Class<T> clazz) {
    return getCommon(
            key,
            v -> {
                if (Objects.isNull(v)) {
                    return defaultValue;
                } else {
                    try {
                        return new ObjectMapper().readValue(v, clazz);
                    } catch (JsonProcessingException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
    );
}

private static <T> T getCommon(String key, Function<String, T> transFunc) {
    try {
        String value = key;
        return transFunc.apply(value);
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

我没有使用TypeReference,而是使用了Class

相关问题