Java 通用通配符构造函数不接受对象?

时间:2021-01-06 21:09:31

标签: java generics constructor

我有一个 RandomizedWrapper 类。这个类包含一个接受列表的构造函数:

public class RandomizedWrapper{

   final int upperBound = 100;
   final List<RandomizerEntry<?>> randomizeList;
   Map<Integer, RandomizerEntry<?>> randomizerMap;

/**
 * Construct a new RandomizedWrapper instance
 * 
 * @param randomizeList - A list containing all randomizable objects
 */
public RandomizedWrapper(final List<RandomizerEntry<?>> randomizeList) {
    
    this.randomizeList = randomizeList;
    this.randomizerMap = new HashMap<>();
   }
}

我想创建这个 RandomizedWrapper 类的新实例。我通过以下代码:

    List<RandomizerEntry<ItemStack>> randomizerList = new ArrayList<>();

    //stuff here

    RandomizedWrapper wrapper = new RandomizedWrapper(randomizerList);//error

当我尝试创建这个新对象时,我遇到了以下错误:

The constructor RandomizedWrapper(List<RandomizerEntry<ItemStack>>) is undefined

这毫无意义。我非常清楚地在 RandomizedWrapper 类中有一个接受 List<RandomizerEntry<?>> 通配符的构造函数。编译器建议的解决方案是“create a constructor that accepts this argument”。我点击它,只是想看看会发生什么,它告诉我“This constructor already exists”。

有人明白这是怎么回事吗?为什么我不能实例化这个对象?

2 个答案:

答案 0 :(得分:4)

这里的问题是 List<RandomizerEntry<ItemStack>> 不是 List<RandomizerEntry<?>> 的子类型,因此您的构造函数不适用于您的参数。请参阅 this section of the Java tutorial 专门解决此误解。

至于 IDE 建议创建另一个构造函数,这是行不通的,因为在 Java 中不可能“重载一个方法,其中每个重载的形参类型都擦除为相同的原始类型”({{3} }).

解决这个问题的一种方法是让你的局部变量的类型与你的构造函数兼容,尽管这当然会限制你可以用它做什么:

List<RandomizerEntry<?>> randomizerList = new ArrayList<>();

答案 1 :(得分:4)

? (wildcars) 主要用于泛型代码不需要任何类型引用并且 RandomizedWrapper 不是需要通配符的类类型。在这种情况下,最好使用类型参数 <T> (Difference between ? (wildcard) and Type Parameter in Java)

public class RandomizedWrapper<T>{

    final int upperBound = 100;
    final List<RandomizerEntry<T>> randomizeList;
    Map<Integer, RandomizerEntry<T>> randomizerMap;

    /**
     * Construct a new RandomizedWrapper instance
     *
     * @param randomizeList - A list containing all randomizable objects
     */
    public RandomizedWrapper(final List<RandomizerEntry<T>> randomizeList) {

        this.randomizeList = randomizeList;
        this.randomizerMap = new HashMap<>();
    }


    public void create(){
        List<RandomizerEntry<Integer>> randomizerList = new ArrayList<>();
        //stuff here
        RandomizedWrapper wrapper = new RandomizedWrapper(randomizerList);//OK
    }
}
相关问题