Generics: cannot convert from <capture#1-of ? extends Object,D> to <S,D>

99封情书 提交于 2020-05-14 16:49:05

问题


I have the following class structure:

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);
    }

My Eclipse compilator gives me the following error:

Type mismatch: cannot convert from CopyMapper<capture#1-of ? extends Object,D> to CopyMapper<S,D>

As far as I know, all generic types extend Object, so I don't see where the problem is?

We are trying to preserve an interface. This is the original method of the interface:

<T> T map(Object source, Class<T> destinationClass)

I tweaked it a little bit so that the classes that use the interface don't get affected:

<S, D> D map(S source, Class<D> destinationClass);

Basically, we are mapping Pojo's, we've been using DozerMapper, but now, the major architect wants compile time safety, and the DozerMapper isn't. For example if a pojo's field gets updated (renamed, deleted) we need to manually update the xml, that describes the mapping between the pojo's (the xml is used in case of nontrivial mapping, for example, when the names of fields of the pojo's don't correspond completely, which is often the case)

Now, we have copy classes, hundreds of them, one for each mapping between pojo's. We are trying to use the Factory Design patter to return a specific mapper class (implementing the CopyMapper interface) based on the source class and destination class.


回答1:


The getClass method returns Class<?> and not Class<S>, as I think you are expecting. See Object#getClass in the API.

As it returns Class<?> you lose type information, so you really have this:

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

You know source class is S so I think you can safely add a cast, but you will get a warning:

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


来源:https://stackoverflow.com/questions/27133142/generics-cannot-convert-from-capture1-of-extends-object-d-to-s-d

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!