I have a rather weird problem with generics, where Java reports a compilation error.
Background: I am creating my own Kafka client wrapper. One thing I need to support is for users of lib to supply their own key serializer class and value serializer class.
Let's say that I have:
import org.apache.kafka.common.serialization.Serializer;
// ...
private Class<? extends Serializer<?>> keySerializerClass;
private Class<? extends Serializer<?>> valueSerializerClass;
// ...
public Builder<K, V> serializeWith(Class<? extends Serializer<?>> keySerializerClass,
Class<? extends Serializer<?>> valueSerializerClass)
{
this.keySerializerClass = keySerializerClass;
this.valueSerializerClass = valueSerializerClass;
return this;
}
Now, at the call-site, if I do:
import org.apache.kafka.common.serialization.StringSerializer;
import io.confluent.kafka.serializers.KafkaAvroSerializer;
// ...
builder.serializeWith(StringSerializer.class, KafkaAvroSerializer.class);
It works perfectly. However, if I attempt :
import org.apache.kafka.common.serialization.StringSerializer;
import io.confluent.kafka.serializers.protobuf.KafkaProtobufSerializer;
// ...
builder.serializeWith(StringSerializer.class, KafkaProtobufSerializer.class);
It screams with a compilation error:
java: incompatible types: java.lang.Class<capture#1 of ?> cannot be converted to java.lang.Class<? extends org.apache.kafka.common.serialization.Serializer<?>>
which does not make any sense to me. After all, KafkaProtobufSerializer
conforms the <? extends Serializer<?>>
<? extends Serializer<?>>
bounded generic:
public class KafkaProtobufSerializer<T extends Message> extends AbstractKafkaProtobufSerializer<T> implements Serializer<T> {
Please tell me that I overlooked some silliness :)
There are a few options you could try, if you have the ability to modify your Builder class:
public Builder<K, V> serializeWith(Class<? extends Serializer<K>> keySerializerClass,
Class<? extends Serializer<V>> valueSerializerClass)
{
this.keySerializerClass = keySerializerClass;
this.valueSerializerClass = valueSerializerClass;
return this;
}
or removing the ? from Serializer:
public Builder<K, V> serializeWith(Class<? extends Serializer> keySerializerClass,
Class<? extends Serializer> valueSerializerClass)
{
this.keySerializerClass = keySerializerClass;
this.valueSerializerClass = valueSerializerClass;
return this;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.