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

标签 java generics wildcard

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

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

最佳答案

使用以下内容:

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

这只是编译器类型推断的一个例子,所以有必要显式地为 T 提供类型参数。 .

从技术上讲:

test3被声明为类型 IAnotherRandomType<?> , 其中?是一个通配符捕获 - 一种表示某些特定未知类型 的一次性类型参数。这就是编译器在说 capture#1-of ? 时所指的内容.当你通过 test3进入createManager , T被推断为 IAnotherRandomType<capture#1-of ?> .

与此同时,test3Manager被声明为类型 IManager<IAnotherRandomType<?>> ,它有一个嵌套通配符 - 它的行为不像类型参数,而是表示任何类型

自泛型 aren't covariant , 编译器无法从 IManager<IAnotherRandomType<capture#1-of ?>> 转换至 IManager<IAnotherRandomType<?>> .

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

关于Java:通配符类型不匹配导致编译错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19736325/

相关文章:

Java 正则表达式和美元符号

Java 正则表达式与括号匹配

java - 赋予一个类以扩展一个Java的值(value)

java - 将输入设置为变量以传递到表中

generics - 具有泛型类型结构值的结构

wildcard - VHDL STD_LOGIC_VECTOR 通配符值

bash - 在 shell 中实现通配符扩展

ios - 数组中的 Swift 不同类型的泛型

swift - 协议(protocol)实例的集合

css - 我可以使用 CSS :visited pseudo class on 'wildcard' links?