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

Mat*_*hew 9 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<>();
   }
}
Run Code Online (Sandbox Code Playgroud)

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

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

    //stuff here

    RandomizedWrapper wrapper = new RandomizedWrapper(randomizerList);//error
Run Code Online (Sandbox Code Playgroud)

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

The constructor RandomizedWrapper(List<RandomizerEntry<ItemStack>>) is undefined
Run Code Online (Sandbox Code Playgroud)

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

有谁明白这里发生了什么?为什么我不能实例化这个对象?

小智 4

这里的问题是,它List<RandomizerEntry<ItemStack>>不是子类型List<RandomizerEntry<?>>,因此您的构造函数不适用于您的参数。请参阅Java 教程的这一部分,其中专门解决了这种误解。

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

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

List<RandomizerEntry<?>> randomizerList = new ArrayList<>();
Run Code Online (Sandbox Code Playgroud)

  • 请注意,鉴于此“随机化器”类的明显用途,它绝对应该是“RandomizedWrapper&lt;E&gt;”。 (3认同)