Java泛型:<B扩展BaseB>不匹配<?扩展BaseB>

ege*_*lev 5 java generics

我有两个同构类型的层次结构.第一个的基本类型是BaseA,第二个的基本类型是BaseB.我知道如何将BaseB的任何子类的任何对象转换为其对应的BaseA子类型.我想实现一个方法,它接受BaseB类型的对象确定其类并构造相应的BaseA子类型的对象.示例代码:

public interface BaseA...
public interface BaseB...
public class DerA implements BaseA...
public class DerB implements BaseB...
...
public interface Transform<A,B> {
    A toA (B b);
}

public class DerAtoDerB implements Transform<DerA,DerB> {
    DerA toA (DerB b){...}
}

public class Transformations {
    private static Map<Class<?>, Transform<? extends BaseA, ? extends BaseB>> _map = 
        new HashMap<>();
static {
    _map.put(DerB.class, new DerAtoDerB());
    }

public static <B extends BaseB> BaseA transform(B b){
    Transform<? extends BaseA, ? extends BaseB> t = _map.get(b.getClass());
    return t.toA(b); // Compile error: Transform<A,B#2> cannot be applied to given types
}
Run Code Online (Sandbox Code Playgroud)

为什么<B extends BaseB>不兼容<? extends BaseB>?此外,如果我尝试实现这样的静态转换方法:

public static BaseA transform(BaseB b){
    Transform<? extends BaseA, ? extends BaseB> t = _map.get(b.getClass());
    return t.toA(b); // Compile error: Transform<A,B> cannot be applied to given types
}
Run Code Online (Sandbox Code Playgroud)

我收到编译错误: Transform<A,B> cannot be applied to given types

任何人都可以解释我对Generics的错误吗?

Jor*_*dão 3

问题在于,在该transform方法中,编译器无法知道类型参数和从映射中获取的类 ( )B extends BaseB中的第二个类型参数实际上代表 的同一个子类。没有什么可以阻止您在映射中存储不兼容的类型:Transform? extends BaseBBaseB

_map.put(DerB.class, new AnotherDerAtoAnotherDerB()); // the types don't match
Run Code Online (Sandbox Code Playgroud)

是保证映射中的类型匹配的人,因此您需要通过将其转换为正确的类型来告诉编译器:

@SuppressWarnings("unchecked")
public static <B extends BaseB> BaseA transform(B b) {
  Transform<? extends BaseA, B> t = 
    (Transform<? extends BaseA, B>)_map.get(b.getClass());
  return t.toA(b);
}
Run Code Online (Sandbox Code Playgroud)