【问题标题】:Generics: cannot convert from <capture#1-of ? extends Object,D> to <S,D>泛型:无法从 <capture#1-of 转换?将 Object,D> 扩展到 <S,D>
【发布时间】:2014-11-25 17:35:48
【问题描述】:

我有以下类结构:

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 之间的映射一个。我们正在尝试使用工厂设计模式根据源类和目标类返回特定的映射器类(实现CopyMapper 接口)。

【问题讨论】:

  • 你是如何让CopyMapperFactory 编译的?
  • 它只是编译。为什么?你认为不应该吗?
  • 没关系,我看错了
  • 你为什么要通过 Class 呢?你不能只通过S吗?
  • 然后我必须将其转换为特定类型,这在编译时是不安全的。

标签: java generics


【解决方案1】:

getClass 方法返回 Class&lt;?&gt; 而不是 Class&lt;S&gt;,正如我认为您所期望的那样。请参阅 API 中的Object#getClass

当它返回 Class&lt;?&gt; 时,你会丢失类型信息,所以你真的有这个:

CopyMapper<?, D> copyMapper = mapperFactory.getMapper(source.getClass(), destinationClass);

您知道源类是S,所以我认为您可以安全地添加演员表,但您会收到警告:

CopyMapper<S, D> copyMapper = mapperFactory.getMapper((Class<S>)source.getClass(), destinationClass);

【讨论】:

  • 所以这是一个安全的演员阵容,因为我确定source 的类是S,对吧?
  • 如果这严格来说是泛型问题,我认为你是对的。但我在这里怀疑的是,他们对 Dozer 的使用存在更深层次的问题。
猜你喜欢
  • 2017-09-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-21
  • 1970-01-01
  • 2014-01-29
  • 1970-01-01
相关资源
最近更新 更多