5

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

以下代码是我正在使用的精简版本。我尝试创建“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<?>>

以前也有人问过类似的问题(见下文);但是,我不知道这个问题是否被认为是它们的重复。我之所以这么说,是因为我无法从这些问题中推断出我的答案。我希望有人能澄清我在使用泛型时做错了什么。

关于 SO 的相关问题是:

4

1 回答 1

4

使用以下内容:

IManager<IAnotherRandomType<?>> test3Manager =
        Factory.<IAnotherRandomType<?>>createManager(test3);

这只是编译器类型推断落空的一种情况,因此有必要显式地为T.

从技术上讲:

test3被声明为具有 type IAnotherRandomType<?>,其中?通配符捕获- 一种代表某些特定未知类型的一次性类型参数。这就是编译器所说的capture#1-of ?. 当您传入 时test3createManagerT推断为IAnotherRandomType<capture#1-of ?>

同时,test3Manager被声明为具有嵌套通配符的 type IManager<IAnotherRandomType<?>>——的行为不像类型参数,而是表示任何类型

由于泛型不是 covariant,编译器无法从IManager<IAnotherRandomType<capture#1-of ?>>to转换为IManager<IAnotherRandomType<?>>.

更多关于嵌套通配符的阅读:

于 2013-11-02T00:09:18.480 回答