java - 为什么通配符类型参数不在自引用类型的包装器范围内
问题描述
我有一个接口,其中包含返回或需要实现类型实例的方法。为此,我创建了一个表单类型变量U extends I<U>
以用作返回类型。目的当然U
是实现类:
interface SelfReferringInterface<U extends SelfReferringInterface<U>> {
}
现在我有一个包含不相关类型变量的实现类:
class RestrictingType<T> implements SelfReferringInterface<RestrictingType<T>> {
}
还有一个围绕 a 实例的类SelfReferringInterface
:
class Wrapper<T extends SelfReferringInterface<T>> {
}
Wrapper
不知何故,对于采用以下通配符实例的类型,我得到一个类型推断错误RestrictingType
:
public class Main {
public static void main(String... args) {
// This type checks
SelfReferringInterface<?> test1;
// This too
RestrictingType<?> test2;
// And this
Wrapper<RestrictingType<Object>> test3;
// This fails
Wrapper<RestrictingType<?>> test4;
// Interestingly this does succeed
Wrapper<? extends RestrictingType<?>> test5;
}
}
编译它会产生以下错误:
Main.java:23: error: type argument RestrictingType<?> is not within bounds of type-variable T
Wrapper<RestrictingType<?>> test4;
^
where T is a type-variable:
T extends SelfReferringInterface<T> declared in class Wrapper
1 error
为什么RestrictingType<?>
不在范围之内T
?为什么功能相似? extends RestrictingType<?>
没有问题?
解决方案
Wrapper<RestrictingType<T>>
适用于任何给定类型T
,因为我们知道Restricting<T>
implements SelfReferringInterface<RestrictingType<T>>
。但是,Wrapper<RestrictingType<?>>
不起作用,因为Restricting<? #1>
可能无法实现SelfReferringInterface<RestrictingType<? #2>>
。通配符?
表示未知类型,在这两个地方可能是两种不同的未知类型。
这是了解为什么必须这样的另一种方法:假设您的Wrapper<T>
类可以包含包装类型的多个项目T
。那么 bound<T extends SelfReferringInterface<T>>
意味着任何一项的类型都应该实现SelfReferringInterface<type of any other item>
,就像 howclass SortedList<T extends Comparable<T>>
意味着列表中的任何一项都应该与列表中的任何其他项进行比较。但是,如果您有Wrapper<RestrictingType<?>>
,您将能够将RestrictingType<String>
和RestrictingType<Integer>
项目添加到其中,因为这两种类型都是 的子类型RestrictingType<?>
。但是,RestrictingType<String>
不执行SelfReferringInterface<RestrictingType<Integer>>
,因此合同被打破。
至于为什么Wrapper<? extends RestrictingType<?>>
有效,我不太确定,但? extends
通配符意味着你不能在其中添加任何项目,所以你不能用它来破坏合同。
推荐阅读
- ruby-on-rails - Ruby 生成的 grpc 类服务名冲突
- java - 如何通过将其中一个值切换为键来创建 HashMap 的 HashMap
- html5-canvas - KonjaJs 使用 toDataUrl 保存背景图像
- r - 有没有办法过滤数据框以将与另一个数据框中的值匹配的值保留?
- java - How to Deserialize unknown primitive json property type using Gson
- batch-file - 有没有办法用批处理启动命令提示符,然后在该命令窗口中运行多个命令?
- java - 在读取 txt 文件时从 1D 数组制作 2D 数组
- vba - 将附件字段文件路径提取到不同的列
- macos - macOS SwiftUI 关闭通过菜单中的 segue 呈现的应用模式 NSHostingController?
- react-native - React-Native Navigation v5:如何更改 tabBarLabel 或 tabBarIcon 以及特定屏幕上选项卡的颜色背景?