Java如何强制使用泛型类型

Java如何强制使用泛型类型,java,generics,Java,Generics,下面是我正在处理的代码示例 interface KafkaRecord {} class Book implements KafkaRecord { //some properties here with getter setter } class BookDeserializer implements Deserializer<Book> { //Deserialiazing bytes to Book } // props is Properties

下面是我正在处理的代码示例

interface KafkaRecord {}

class Book implements KafkaRecord { 
    //some properties here with getter setter
}

class BookDeserializer implements Deserializer<Book> {
    //Deserialiazing bytes to Book 
}


// props is Properties which having key value pair for configuration. 
Consumer<String, KafkaRecord> consumer = new KafkaConsumer<>(props);
ConsumerRecords<String, KafkaRecord> records = 
        consumer.poll(Duration.ofMillis(getTimeout()));

records.foreach(bean -> SomeComponent.process((Book) bean));
从哪个地方打过来的-

ConsumerRecords<String, KafkaRecord> pencilRecords = pencilConsumer.poll(Duration.ofMillis(1000));
pencilRecords.forEach(bean -> playWithRecord(bean.value()));
如果我们将playWithRecord()更新为接受Object类型的参数,而不是KafkaRecord,它就会工作

在我看来,它的发生是因为类型已被删除-

ConsumerRecords<String, KafkaRecord> pencilRecords = pencilConsumer.poll(Duration.ofMillis(1000));
ConsumerRecords pencilRecords=pencilConsumer.poll(持续时间1000百万);

实际上,这根本不是一般类型/擦除问题

考虑这一点:

SomeOtherComponent.process((Pencil) bean))
在编译时,问题是:can
bean
。。。我们知道它实现了KafakaRecord。。。可能是
Pencil
Pencil
的某个子类

现在我们知道它不能是
Pencil
的实例,因为
Pencil
没有实现
KafakaRecord
。但假设我声明如下:

class ColoredPencil extends Pencil implements KafkaRecord {
    ...
}
如果运行时我们的
记录
集合由
KafkaRecord
实例组成,这些实例是
coloredpencil
对象,那么它们将是
Pencil
的实例,因此类型转换不应是编译时错误

通常,从接口类型到类类型的转换不是编译时错误,除非类类型是
final
,并且类不直接或间接实现接口


在编写代码时,是否有任何方法可以报告此问题。那支铅笔必须实现卡夫卡录音

不使用编写的代码

您可以尝试以下方法:

interface <T extends KafkaRecord> KafkaDeserializer extends Deserializer<T> {}

class PencilDeserializer implements KafkaDeserializer<Pencil> {
     // Deserialiazing bytes to Pencil
}
接口KafkaDeserializer扩展反序列化程序{} 类PencilDeserializer实现KafkaDeserializer{ //将字节反序列化为铅笔 } 如果
Pencil
未声明为
KafkaRecord
的子类型,则后者将给出编译错误。这可能足以满足您的需要,特别是如果您可以确保所有反序列化程序都实现
KafkaDeserializer
,而不是
反序列化程序
。(我对卡夫卡了解不够,不知道这是否有道理。)


另一种方法是简单地将
Pencil
声明为
final

这似乎是由于一般擦除造成的


我不得不在另一个论坛上讨论这个问题,因为我在这里没有得到太多的回应@Stephen已经解释了如何强制java在编译时报告它。

如果代码正常工作,问题是什么?如果我们不知道什么是
ConsumerRecords
,它的方法
foreach()
是如何声明的,我们怎么知道呢但基本上,您的代码通过强制转换绕过了类型安全性,现在您要问的是如何使代码类型安全?回答:停止施放@清扫器-是代码正在工作。问题是ConsumerRecords records=consumer.poll(Duration.ofMillis(getTimeout());//Pencil没有将kafka-clients-2.4.0.jar作为消费者实现。poll返回Pencil对象,左侧没有抱怨。@Andreas-公共类ConsumerRecords实现Iterable{},它来自kafka-clients-2.4.0.jar,正如我在前面的评论中提到的,而poll工作正常。在第二行中,我做了施法,因为我想我得到了铅笔,施法很好。不要在注释中显示代码。编辑问题并在此处显示代码,以澄清问题,以及在何处可以更好地格式化代码以便于人类阅读。感谢Stephen抽出时间回答问题。我已经添加了GIT url以进行澄清。另一件事是Pencil没有扩展/实现任何与KafkaReocrd相关的类/接口,但是CustomExecutor.java中的L26行可以正常工作。如何才能在编译/运行时报告此问题。感谢Stephen的详细解释。还有一个问题是Java在运行时不会检查Pencil对象是否在KafkaRecord(Pencil和KafkaRecord没有任何关系)类型变量中传入。
ConsumerRecords<String, KafkaRecord> pencilRecords = pencilConsumer.poll(Duration.ofMillis(1000));
SomeOtherComponent.process((Pencil) bean))
class ColoredPencil extends Pencil implements KafkaRecord {
    ...
}
interface <T extends KafkaRecord> KafkaDeserializer extends Deserializer<T> {}

class PencilDeserializer implements KafkaDeserializer<Pencil> {
     // Deserialiazing bytes to Pencil
}