如何在Kotlin中实现等价于Java原始泛型的Serializer且不修改register签名?
Kotlin泛型Serializer实现问题:将Java原始泛型实现转为纯Kotlin
已定义的Kotlin泛型接口与类
Transformer接口
interface Transformer<T, R> { fun transform(it: T): R }
DefaultNullableTransformer类
该类用于处理空输入,将非空值委托给非空Transformer:
data class DefaultNullableTransformer<T, R>( val transformer: Transformer<T, R>, val default: R ) : Transformer<T?, R> { override fun transform(it: T?): R { val data = it ?: return default return transformer.transform(data) } }
自定义序列化框架核心类
interface Serializer<T, D> { fun serialize(it: T, registry: SerializerRegistry): D fun deserialize(it: D, registry: SerializerRegistry): T } data class TypedData<T : Any>(val type: KClass<out T>, val data: Any) class SerializerRegistry(private val defaultSerializer: Serializer<*, *>? = null) { private val serializers = mutableMapOf<KClass<*>, Serializer<*, *>>() fun <T : Any> register(type: KClass<T>, serializer: Serializer<T, *>) { serializers[type] = serializer } fun <T : Any> serialize(it: T) = TypedData( it::class, get(it::class).serialize(it, this) ) fun <T : Any> deserialize(it: TypedData<T>): T = get(it.type).deserialize(it.data, this) as T private fun get(type: KClass<out Any>): Serializer<Any?, Any> { val serializer: Serializer<Any?, Any>? = serializers[type] as? Serializer<Any?, Any> ?: (defaultSerializer as Serializer<Any?, Any>?) return serializer ?: throw UnsupportedOperationException("Serializer for $type is not registered") } }
问题描述
我在实现类型擦除的Serializer时遇到了阻碍。在Java中,我可以通过原始泛型实现DefaultNullableTransformerSerializer,代码如下:
Java原始泛型实现
public class DefaultNullableTransformerSerializer implements Serializer<DefaultNullableTransformer, DefaultNullableTransformerSerializer.SerializedData> { @Override public SerializedData serialize(DefaultNullableTransformer transformer, SerializerRegistry registry) { TypedData<Transformer> transformerData = registry.serialize(transformer.getTransformer()); Optional<TypedData<?>> defaultData = Optional.ofNullable(transformer.getDefault()).map(registry::serialize); return new SerializedData(transformerData, defaultData.orElse(null)); } @Override public DefaultNullableTransformer deserialize(SerializedData data, SerializerRegistry registry) { Transformer transformer = registry.deserialize(data.getTransformer()); Object defaultObj = data.getDefault() != null ? registry.deserialize(data.getDefault()) : null; return new DefaultNullableTransformer<>(transformer, defaultObj); } public static class SerializedData { private final TypedData<Transformer> transformer; private final TypedData<?> defaultData; public SerializedData(TypedData<Transformer> transformer, TypedData<?> defaultData) { this.transformer = transformer; this.defaultData = defaultData; } public TypedData<Transformer> getTransformer() { return transformer; } public TypedData<?> getDefault() { return defaultData; } } }
该Java类可以通过以下代码正常注册:
register(DefaultNullableTransformer::class, DefaultNullableTransformerSerializer())
但我尝试用Any?和*将其转换为Kotlin时始终失败。我知道Kotlin的类型系统比Java更严格,想请教:是否可以在不修改SerializerRegistry.register方法签名的前提下,用纯Kotlin实现同样的功能?
另外,我还尝试了带泛型参数的Java实现:
带泛型参数的Java实现
public class DefaultNullableTransformerSerializer<T, R> implements Serializer<DefaultNullableTransformer<T, R>, DefaultNullableTransformerSerializer.SerializedData<T, R>> { @Override public SerializedData<T, R> serialize(DefaultNullableTransformer<T, R> transformer, SerializerRegistry registry) { TypedData<Transformer<T, R>> transformerData = registry.serialize(transformer.getTransformer()); Optional<TypedData<?>> defaultData = Optional.ofNullable(transformer.getDefault()).map(registry::serialize); return new SerializedData<>(transformerData, defaultData.orElse(null)); } @Override public DefaultNullableTransformer<T, R> deserialize(SerializedData<T, R> data, SerializerRegistry registry) { Transformer<T, R> transformer = registry.deserialize(data.getTransformer()); Object defaultObj = data.getDefault() != null ? registry.deserialize(data.getDefault()) : null; return new DefaultNullableTransformer<>(transformer, (R) defaultObj); } public static class SerializedData<T, R> { private final TypedData<Transformer<T, R>> transformer; private final TypedData<?> defaultData; public SerializedData(TypedData<Transformer<T, R>> transformer, TypedData<?> defaultData) { this.transformer = transformer; this.defaultData = defaultData; } public TypedData<Transformer<T, R>> getTransformer() { return transformer; } public TypedData<?> getDefault() { return defaultData; } } }
但用register(DefaultNullableTransformer::class, DefaultNullableTransformerSerializer())注册时会出现类型不匹配,无法编译。
内容的提问来源于stack exchange,提问作者alturkovic
相关产品推荐
相关产品推荐

