Java:通配符类型不匹配导致编译错误

我在我的项目中创建了一个工厂类,它允许我(理论上)为任何(支持的)给定类型创建管理器。 与管理器交互允许我改变给定类型的某些属性。 我面临的问题是,当我尝试为generics类型创建一个管理器时,编译器会破坏我的希望和梦想。

以下代码是我正在使用的精简版本。 我尝试创建’test3Manager’的行不会编译,我试图理解为什么会这样。 它下面的行显示了一个’解决方法’,我试图避免。

import java.util.List; public class GenTest { public static void main(String[] args) { String test1 = ""; IRandomType test2 = null; IAnotherRandomType test3 = null; IManager test1Manager = Factory.createManager(test1); IManager<IRandomType> test2Manager = Factory.createManager(test2); IManager<IAnotherRandomType> test3Manager = Factory.createManager(test3); // Doesn't compile. Why? // Work around? IManager test3ManagerTmp = Factory.createManager(test3); IManager<IAnotherRandomType> test3Manager2 = (IManager<IAnotherRandomType>) test3ManagerTmp; } public interface IRandomType {} public interface IAnotherRandomType {} public interface IManager {} public static class Factory { public static  IManager createManager(T object) { return null; } } } 

确切的编译错误消息是:

  Type mismatch: cannot convert from GenTest.IManager<GenTest.IAnotherRandomType> to GenTest.IManager<GenTest.IAnotherRandomType> 

之前已经提出了类似的问题(见下文); 但是,我不知道这个问题是否被视为重复。 我只是陈述这一点,因为我无法从这些问题中推断出我的答案。 我希望有人可以澄清我使用仿制药时我做错了什么。

关于SO的相关问题是:

  • 有界通配符相关的编译器错误
  • 不兼容的通配符类型

使用以下内容:

 IManager> test3Manager = Factory.>createManager(test3); 

这只是编译器的类型推断落在其面上的情况,因此必须明确地为T提供类型参数。

技术上更:

test3声明类型为IAnotherRandomType ,其中? 是一个通配符捕获 – 一种表示某些特定未知类型的一次性类型参数。 这就是编译器所说的capture#1-of ? 。 将test3传递给createManagerT会被推断为IAnotherRandomType

同时, test3Manager被声明为具有类型IManager> ,它具有嵌套通配符 – 它不像行参数,而是表示任何类型

由于generics不是协变的 ,因此编译器无法将IManager>IManager>

有关嵌套通配符的更多信息:

  • generics方法上的多个通配符使Java编译器(和我!)非常混淆
  • Java通用列表>
  • 通配符之间存在哪些超子集关系?