值受键的类型参数限制的Java泛型Map

mspsb9vt  于 2023-02-15  发布在  Java
关注(0)|答案(1)|浏览(146)

我如何使用泛型声明一个Map变量,它有X的Class作为Key,和X的相关的Serializer作为Value
例如,我想拥有一个可以包含以下内容的Map:
K、V
类,新的BigDecimalSerializer()
类,新的本地日期序列化程序()
类,新建日期序列化程序()
序列化器示例:

public class BigDecimalSerializer extends JsonSerializer<BigDecimal> {

    @Override
    public void serialize(BigDecimal value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        gen.writeString(FormatUtils.format(value));
    }

}

我试过Map<Class<?>, ? extends JsonSerializer<?>>

@Getter
@AllArgsConstructor
public class CsvWriterConfig {
    
    private final Map<Class<?>, ? extends JsonSerializer<?>> serializers;
    private final char separator;
    
}

但是将它们添加到SimpleModule中

SimpleModule module = new SimpleModule();
serializers.forEach(module::addSerializer);

给我一个错误:

The type SimpleModule does not define addSerializer(Class<capture#5-of ?>, capture#4-of ? extends JsonSerializer<?>) that is applicable here

简单模块addSerializer是:

public <T> SimpleModule addSerializer(Class<? extends T> type, JsonSerializer<T> ser)
{
    _checkNotNull(type, "type to register serializer for");
    _checkNotNull(ser, "serializer");
    if (_serializers == null) {
        _serializers = new SimpleSerializers();
    }
    _serializers.addSerializer(type, ser);
    return this;
}
4xrmg8kj

4xrmg8kj1#

目前还没有很好的解决办法。
一种可能的方法是使用原始类型(并删除任何泛型)
另一种方法是添加一个方法来向模块添加串行化程序,并在方法中强制类型转换:

@SuppressWarnings("unchecked")
    private <T> void addSerializers(SimpleModule module) {
        this.serializers.forEach((type, serializer) ->
                module.addSerializer((Class<? extends T>) type, (JsonSerializer<T>) serializer));
    }

顺便说一句,上面的代码来自spring-web源代码
第三种方法是使用访问器方法为Map创建 Package 器,这将确保不会添加不正确的类型-序列化程序对。例如:

SerializersWrapper serializersWrapper = new SerializersWrapper();
        SimpleModule module = new SimpleModule();
        serializersWrapper.getAll().forEach(module::addSerializer);

并且 Package 器代码是

import com.fasterxml.jackson.databind.JsonSerializer;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

public class SerializersWrapper {
    private final Map<Class,JsonSerializer> serializers = new HashMap<>();

    public <T> void addSerializer(Class<T> type, JsonSerializer<T> serializer) {
        serializers.put(type, serializer);
    }

    public <T> JsonSerializer<T>  getSerializer(Class<T> type){
        return serializers.get(type);
    }

    public <T> Map<Class<T>,JsonSerializer<T>> getAll(){
        return (Map<Class<T>, JsonSerializer<T>>) (Map) Collections.unmodifiableMap(serializers);
    }
}

相关问题