简体   繁体   中英

Incompatible types: java.lang.Class<capture#1 of ?> cannot be converted to

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM