我有一个使用此界面的方法:
public <A extends Message, B extends Message> MessageConverter<A, B>
getDefaultConverterFor(Class<A> inputClass, Class<B> outputClass);
其中的想法是您有一个类型A的消息要转换为类型B的消息,并且您希望从可用的已注册转换器的存储库中获取转换器。不幸的是,我遇到了很大的麻烦,在这两端的类型都按照我的预期工作。
更具体地说,我正在尝试这样做:
public <M extends Message> Message convert(M m)
{
MessageConverter<M, DictMessage> converter =
getDefaultConverterFor(m.getClass(), DictMessage.class);
return converter.convert(m);
}
(即接收任何类型的消息并将其转换为DictMessage)但它在getDefaultConverter行上给出了编译错误:
Type mismatch: cannot convert from MessageConverter<capture#1-of ? extends Message,DictMessage> to MessageConverter<Message,DictMessage>".
我甚至不确定为什么会这样,更不用说如何修复它了。我想这与getClass返回的类没有完全匹配M有关,但我真的不知道。我可以相信,这可能实际上是行不通的,但我想不出任何破坏它的特定例子......思想?
答案 0 :(得分:1)
我有一个问题,Object.getClass()返回Class<?>
一段时间了。编译器不知道m.getClass()
是Class<M>
,但你可以通过演员来解决这个问题。
@SuppressWarnings("unchecked")
MessageConverter<M, DictMessage> converter =
getDefaultConverterFor((Class<M>) m.getClass(), DictMessage.class);
答案 1 :(得分:1)
public <M extends Message> Message convert(M m) {
Class<M> abc = m.getClass(); // compile error
...
}
不起作用。
您可以在getClass()
来电之前添加类型广告。
public <M extends Message> Message convert(M m) {
Class<M> abc = (class<M>)m.getClass(); // ok
...
}
或者您可以在方法中添加其他类参数:
public <M extends Message> Message convert(M m, Class<M> mClass) {
// use mClass instead of m.getClass()
...
}
或者您可以更改MessageConverter
变量的类型参数:
public <M extends Message> Message convert(M m) {
MessageConverter<? extends Message, DictMessage> converter = this.getDefaultConverterFor(m.getClass(), DictMessage.class);
getClass()
返回值的Javadoc说:
The java.lang.Class object that represents the runtime class of the object.
The result is of type Class<? extends X> where X is the erasure of the static
type of the expression on which getClass is called.
因此,您的getClass()
的返回类型为Class<? extends Message>
,而不是Class<Message>
。
答案 2 :(得分:1)
以下是完全输入的内容。
public class MessageConverter<INP extends Message, OUTP extends Message> {
private Class<INP> inputClass;
private Class<OUTP> outputClass;
public MessageConverter(Class<INP> inputClass, Class<OUTP> outputClass) {
this.inputClass = inputClass;
this.outputClass = outputClass;
}
public OUTP convert(INP m) {
try {
return outputClass.newInstance();
} catch (InstantiationException | IllegalAccessException ex) {
throw new IllegalStateException(ex);
}
}
}
public <INP extends Message, OUTP extends Message> MessageConverter<INP, OUTP>
getDefaultConverterFor(Class<INP> inputClass, Class<OUTP> outputClass) {
MessageConverter<INP, OUTP> mc = new MessageConverter<INP, OUTP>(inputClass, outputClass);
return mc;
}
public <INP extends Message> MessageConverter<INP, DictMessage>
getDictConverterFor(Class<INP> inputClass) {
MessageConverter<INP, DictMessage> mc =
new MessageConverter<INP, DictMessage>(inputClass, DictMessage.class);
return mc;
}