Pau*_*ton 15 java generics covariance
考虑这个例子:
public final class Main<T extends Main<T>> {
public static void main(String[] args) {
Main<?> main = new Main<>();
}
}
Run Code Online (Sandbox Code Playgroud)
这完全编译.但是当我尝试在不使用菱形的情况下进行编译时,我能够使用它的唯一方法是使用原始类型.
Main<?> main = new Main();
Run Code Online (Sandbox Code Playgroud)
没有原始类型的尝试不起作用:
Main<?> main = new Main<?>(); // None of
Main<?> main = new Main<Main<?>>(); // these
Main<?> main = new Main<Main<Main<?>>>(); // compile
Run Code Online (Sandbox Code Playgroud)
那么为什么钻石的原始版本有效呢?你写的时推断类型是什么Main<?> main = new Main<>();?
它是推断原始类型,还是推断某种无限嵌套类型?
Main<Main<Main<Main<...>>>>
Run Code Online (Sandbox Code Playgroud)
in?是Main<?>一个占位符,在绑定时可以是任何类型。
您在源代码中编写的每个?内容都可能是不同的类型(在错误消息中称为capture#2-of ?),因此您不能将 的表达式分配Main<?>给任何可表达类型的变量。
菱形运算符在这里起作用,因为它的类型推断在?捕获 s 之后运行 - yourMain<>变为 not Main<?>but Main<capture#1 of ?>(假设您Main<?>将其分配给 is capture#1)。
换句话说,菱形运算符是唯一可以直接指定特定捕获的语法,就像var在 C# 中是唯一可以直接指定匿名类型的语法一样。(请注意,使用方法类型推断的重载解析也可以解析为特定的捕获)
至于代码的含义,new Main<?>()(对于 的任何捕获?) 是 的简写Main<? extends Object>,或者,在您的情况下,Main<? extends Main<same ?>>(编译器自动将 限制?为类型的约束)。这成为 的协变视图Main<>,其中类型参数只能转换为Main<?>(因为它实际上可能是任何类型,因此您不能假设超出约束的任何内容)。
通常,没有理由实际创建这样的东西。
| 归档时间: |
|
| 查看次数: |
848 次 |
| 最近记录: |