我在项目中创建了一个工厂类,从理论上讲,该类允许我为任何(受支持的)给定类型创建管理器。与管理器进行交互使我可以更改给定类型的某些属性。我面临的问题是,当我尝试为泛型类型创建管理器时,编译器粉碎了我的希望和梦想。
以下代码是我正在使用的简化版本。我尝试创建“
test3Manager”的行将不会编译,并且我试图了解为什么会这样。它下面的线显示了一种“解决方法”,我正试图避免这种情况。
import java.util.List;
public class GenTest {
public static void main(String[] args) {
String test1 = "";
IRandomType<String> test2 = null;
IAnotherRandomType<?> test3 = null;
IManager<String> test1Manager = Factory.createManager(test1);
IManager<IRandomType<String>> 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<T> {}
public interface IAnotherRandomType<T> {}
public interface IManager<T> {}
public static class Factory {
public static <T> IManager<T> createManager(T object) {
return null;
}
}
}
确切的编译错误消息是:
Type mismatch: cannot convert from GenTest.IManager<GenTest.IAnotherRandomType<capture#1-of ?>> to GenTest.IManager<GenTest.IAnotherRandomType<?>>
之前已经问过类似的问题(见下文);但是,我不知道这个问题是否被认为是它们的重复。我仅说明这一点,因为我无法从这些问题中得出答案。我希望有人可以澄清我对泛型的使用做错了什么。
使用以下内容:
IManager<IAnotherRandomType<?>> test3Manager =
Factory.<IAnotherRandomType<?>>createManager(test3);
这只是编译器类型推断浮出水面的一种情况,因此有必要显式提供的类型参数T
。
从技术上讲:
test3
声明为具有类型IAnotherRandomType<?>
,其中?
是 通配符捕获 -一种表示 某种特定未知类型
的一次性类型参数。这就是编译器所说的capture#1-of ?
。当您test3
进入时createManager
,T
将推断为IAnotherRandomType<capture#1-of ?>
。
同时,test3Manager
声明有类型IManager<IAnotherRandomType<?>>
,其中有一个 嵌套的通配符
-它并不像一个类型参数,而是代表 任何类型 。
由于泛型不是协变的,因此编译器无法将转换IManager<IAnotherRandomType<capture#1-of?>>
为IManager<IAnotherRandomType<?>>
。
与有界通配符相关的编译器错误 应兼容的不兼容通配符类型
与有界通配符相关的编译器错误 Java:通配符类型不匹配导致编译错误
我不明白为什么会出现这些编译错误: 1: 类型列表中的add(capture#1-of?extends Exec.Bird)方法不适用于参数(Exec.Sparrow) 2: 方法添加(捕获#2-of?扩展Exec.Bird)类型列表中的参数(Exec.鸟)
应该如何声明“GenericBo Bo”实例?正确的代码是什么?
我得到以下编译错误: 当我编译(在Eclipse Juno中使用JDK 1.7.0)以下代码时: null 这样我就可以测试我所有的排序实现并测试它们。我想将结果与Java的排序实现进行比较,所以我也在编写这个接口的实现,它在内部只调用Java的排序方法。这就是我面对问题的地方。
我有以下具有以下方法的类。 GsonHelper为我提供了一些 在Java 7之前,我一直使用这种方法,例如: 这工作得很好。因为这个方法会返回一个布尔值,我可以在“if”中使用它。但是当我换到Java 8时,这就不可能了。编译器抱怨: 类型不匹配:无法从对象转换为布尔值 我知道java.lang.Boolean可以为空。我可以通过以下方式解决这个问题: 但我很好奇,为什么这在Java 7中有效,