我有以下类结构:
public interface CopyMapper<S, D> {
public D map(S sourceObject);
}
public interface CopyMapperFactory {
public <S, D> CopyMapper<S, D> getMapper(Class<S> sourceClass, Class<D> destinationClass);
}
public class Mapper {
public <S, D> D map(S source, Class<D> destinationClass) {
//This is where I get compile time error
CopyMapper<S, D> copyMapper = mapperFactory.getMapper(source.getClass(), destinationClass);
return copyMapper.map(source);
}
我的Eclipse编译器给了我以下错误:
Type mismatch: cannot convert from CopyMapper<capture#1-of ? extends Object,D> to CopyMapper<S,D>
据我所知,所有通用类型都延伸Object
,所以我不知道问题出在哪里?
我们正在努力保留一个界面。这是界面的原始方法:
<T> T map(Object source, Class<T> destinationClass)
我稍微调整了一下,以便使用界面的课程不会受到影响:
<S, D> D map(S source, Class<D> destinationClass);
基本上,我们正在映射Pojo,我们一直在使用DozerMapper,但现在,主要的架构师希望编译时安全,而DozerMapper并不是。例如,如果pojo的字段被更新(重命名,删除),我们需要手动更新xml,它描述了pojo之间的映射(例如,在非平凡映射的情况下使用xml)当pojo的字段名称不完全对应时(通常是这种情况)
现在,我们有复制类,数百个,一个用于pojo之间的每个映射。我们正在尝试使用Factory Design模式根据源类和目标类返回特定的映射器类(实现CopyMapper
接口)。
答案 0 :(得分:4)
我认为您期待的是getClass
方法返回Class<?>
而非Class<S>
。请参阅API中的Object#getClass
。
当它返回Class<?>
时,你会丢失类型信息,所以你真的有这个:
CopyMapper<?, D> copyMapper = mapperFactory.getMapper(source.getClass(), destinationClass);
你知道源类是S
所以我认为你可以安全地添加一个演员阵容,但你会收到警告:
CopyMapper<S, D> copyMapper = mapperFactory.getMapper((Class<S>)source.getClass(), destinationClass);