有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java泛型不兼容类型(不存在类型变量的实例)

这基本上是我第一次接触Java泛型类型,我不知道下面的代码有什么问题

我有一个helper类Helper,它带有一个静态函数inRangeusng泛型类型,该泛型类型应该从输入列表返回对象列表,这些对象位于索引index处的对象周围的某些range(我还没有测试它,如果它工作正确与否,在这里不是问题):

public class Helper {
public static <T> List<T> inRange(List<T> list, int index, int range) {
    List<T> res = new ArrayList<T>();
    int N = list.size();
    assert(index < N);
    if (N == 0)
        return res;
    int i, j;

    /* right range */
    i = (index + 1) % N;
    j = 0;
    while (i != index && j < range) {
        res.add(list.get(i));
        i = (i + 1) % N;
        j++;
    }

    /* left range */
    i = (N + index - 1) % N;
    j = 0;
    while (i != index && j < range && !res.contains(list.get(i))) {
        res.add(lista.get(i));
        i = (N + i - 1) % N;
        j++;
    }

    return res;
}
}

然后我想在课堂上使用它:

import java.util.ArrayList;

public class StrategyA extends StrategyB {
public Decision makeDecision(GameView gameView, Action action, View playerView) {
    int pos = gameView.activePlayersViews().indexOf(playerView);
    assert(pos != -1);

    ArrayList<View> inRange = Helper.inRange(gameView.activePlayersViews(), pos, 
            playerView.range());
    // todo ...
    return new Decision(Decision.KindOfDecision.DO_NOTHING, 0);

}
}

其中gameView.activePlayersView()ArrayList<View>类型

然后从我的IDE(IntelliJ IDEA)在线调用inRange(..)我得到

Error:(8, 56) java: incompatible types: no instance(s) of type variable(s) T exist so that java.util.List<T> conforms to java.util.ArrayList<View>

即使我将泛型类型T直接更改为View,我仍然会遇到这个错误


共 (5) 个答案

  1. # 1 楼答案

    ArrayListList接口的一个实现
    因此,所有ArrayList实例都是List实例,但所有List实例不一定都是ArrayList

    因此,当您调用此方法时:

    public static <T> List<T> inRange(List<T> list, int index, int range) {
    

    您不能将其结果分配给ArrayList,因为您正在执行以下操作:

    ArrayList<View> inRange = Helper.inRange(...);
    

    继续按接口编程,并在两侧使用List

    List<View> inRange = Helper.inRange(...);
    
  2. # 2 楼答案

    发生这种情况是因为inRange()返回类型List<T>。您可以使用类型List或任何超类型将结果存储在引用中

    请尝试使用以下代码:

    List<View> inRange = Helper.inRange(gameView.activePlayersView(), pos, 
                playerView.range());
    
  3. # 3 楼答案

    试着做:

    List<View> inRange = Helper.inRange(gameView.activePlayersView(), pos, 
            playerView.range());
    

    并检查以下内容:

    res.add(lista.get(i));
    

    这个班没有lista

  4. # 4 楼答案

    您需要将类型ArrayList强制转换为List

    ArrayList<View> inRange = Helper.inRange((List<View>) gameView.activePlayersViews(), pos, 
    playerView.range());
    
  5. # 5 楼答案

    最小化示例,如(使用模板化列表类型的整数):

    class Ideone
    {
        public static void main (String[] args) throws java.lang.Exception
        {
            List<Integer> list = new ArrayList<Integer>();
            ArrayList<Integer> inRange = Helper.inRange(list, 0,1);
        }
    }
    
    class Helper {
        public static <T> List<T> inRange(List<T> list, int index, int range) {
            List<T> res = new ArrayList<T>();
            return res;
        }
    }
    

    然后,即使您将模板类型排除在图片之外:

    ArrayList inRange = Helper.inRange(list, 0,1);
    
    public static List inRange(List list, int index, int range) { ... }
    

    您可以看到,虽然helper静态方法返回一个列表,但您正在尝试将其分配给ArrayList,这是您的问题,因为ArrayList是List的一个具体实现,但是您不能将对泛型列表的引用分配给ArrayList的具体实现

    只需更改为:

    List<View> inRange = Helper.inRange(gameView.activePlayersViews(), pos, 
            playerView.range());
    

    你可以走了:https://ideone.com/MXZxqz