本文介绍了Java泛型:< B扩展BaseB>不符合<?扩展BaseB>的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个同构类型层次结构。第一个基本类型是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实现Transform< DerA,DerB> {
DerA toA(DerB b){...}
}

公共类转换{
private static Map< Class<?>,变换<扩展BaseA,?扩展BaseB>> _map =
new HashMap<>();
static {
_map.put(DerB.class,new DerAtoDerB());
}

public static< B extends BaseB> BaseA变换(B b){
变换<扩展BaseA,?扩展BaseB> t = _map.get(b.getClass());
return t.toA(b); //编译错误:变换< A,B#2>不能应用于给定的类型
}

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

  public static BaseA transform(BaseB b){
Transform< ;?扩展BaseA,?扩展BaseB> t = _map.get(b.getClass());
return t.toA(b); //编译错误:转换< A,B>无法应用于给定类型
}

我得到一个编译错误:变换< A,B个不能应用于给定的类型



任何人都可以解释我在做什么错误的泛型?

方法中,编译器无法知道类型参数 B扩展了BaseB ,并在 Transform 类(>扩展了BaseB >)从映射中获得,实际上代表 BaseB 的相同子类。没有什么能阻止你在映射中存储不兼容的类型:

  _map.put(DerB.class,new AnotherDerAtoAnotherDerB()); //类型不匹配

是担保人地图中的类型匹配,所以你需要通过 将它转换为正确的类型来告诉编译器:

  @SuppressWarnings(unchecked)
public static< B extends BaseB> BaseA变换(B b){
变换<扩展BaseA,B> t =
(变换< ;?扩展BaseA,B>)_ map.get(b.getClass());
return t.toA(b);
}


I have two isomorphic type hierarchies. The base type of the first one is BaseA and the base type of the second one is BaseB. I know how to transform any object of any subclass of BaseB to its corresponding subtype of BaseA. I want to implement a method which takes object of type BaseB determines its class and constructs an object of the corresponding subtype of BaseA. Example code:

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
}

Why <B extends BaseB> is not compatible with <? extends BaseB> ? Also if I try implementing the static transform method like this:

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
}

I get a compilation error: Transform<A,B> cannot be applied to given types

Can anyone explain me what I am doing wrong with Generics?

解决方案

The problem is that in the transform method the compiler can't know that the type parameter B extends BaseB and the second type parameter in the Transform class (? extends BaseB) that was gotten from the map actually represent the same subclass of BaseB. Nothing stops you from storing an incompatible type in the map:

_map.put(DerB.class, new AnotherDerAtoAnotherDerB()); // the types don't match

You are the one who guarantees that the types in the map match, so you need to tell the compiler by casting it to the correct type:

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

这篇关于Java泛型:&lt; B扩展BaseB&gt;不符合&lt;?扩展BaseB&gt;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-26 21:59