发现了有关使我烦恼的无限制通配符的事实。例如:
public class Test {
private static final Map<Integer, Map<Integer, String>> someMap = new HashMap<>();
public static void main(String[] args) {
getSomeMap();
}
static Map<?, Map<?, ?>> getSomeMap() {
return someMap; //compilation fails
}
}
尽管可以使用Map<?, ?>
或Map<?, Map<Integer, String>>
返回类型,但失败。
有人可以告诉我确切原因吗?提前致谢。
更新资料
我认为,对于此问题,我似乎理解并最简单的解释(忽略所有这些复杂的规则)是Capture
Conversion(link)中的最后一个注释:Capture conversion is not applied recursively.
了解通配符类型的含义很重要。
您已经了解了,您可以将您Map<Integer, Map<Integer, String>>
的Map<?, ?>
as Map<?, ?>
隐式指定为任意类型,而对于任何可能引用了声明的type的人来说都是未知的Map<?, ?>
。因此,您可以将 任何 地图分配给Map<?, ?>
。
相反,如果你有一个Map<?, Map<?, ?>>
它有一个未知的密钥类型,但值类型是 不
知道。它的Map<?,?>
类型,还记得上面的信息,可以与被分配 任何 地图。
因此,以下代码是合法的:
Map<?, Map<?, ?>> map=new HashMap<>();
map.put(null, Collections.<String,String>singletonMap("foo", "bar"));
map.put(null, Collections.<Double,Integer>singletonMap(42.0, 1000));
map.put(null, Collections.<Object,Boolean>singletonMap(false, true));
在这里,我们放置了一个null
键,因为对于键,我们put
什么都做不到,而是将任意类型的映射作为值,因为这就是值类型的Map<?, ?>
含义:可以从任意映射中分配值。注意,通过遍历条目,我们还可以将具有非null
键的其他条目设置为任意映射。
因此,我非常确定您不希望将您的分配Map<Integer, Map<Integer, String>>
给a Map<?, Map<?, ?>>
并在以后发现不Map<Integer, String>
作为值的任意映射,并且您很高兴编译器不允许这样做。
您实际要做的是将地图分配给键和值类型都未知的类型,但仍然告诉您值是地图:
Map<Integer, Map<Integer, String>> someMap = new HashMap<>();
Map<?, ? extends Map<?, ?>> map=someMap;
在通用类型系统中,它Map<Integer, String>
是的子类型,Map<?, ?>
因此您可以将其分配给Map<?, ?>
和? extends Map<?, ?>
。此子类型关系与String
to
的关系没有不同Object
。您可以将任何值分配给String
类型的变量,Object
但是如果您有一个Map<?,String>
,则不能将其分配给,Map<?,Object>
而只能Map<?, ? extends Object>
由于相同的原因:映射应继续包含String
s作为值,而不是接收任意对象。
请注意,您可以解决此限制。你可以说:
Map<Integer, Map<Integer, String>> someMap = new HashMap<>();
Map<?, Map<?, ?>> map=Collections.unmodifiableMap(someMap);
由于返回的映射unmodifiableMap
不允许进行任何修改,因此可以扩展键和值类型。Map<?, ?>
查询映射时,包含的值具有指定的类型(即),但是尝试放入任意映射值(尽管编译器未拒绝),但将在运行时拒绝。
问题内容: 为什么这样做: 虽然这会产生类型不匹配错误: 为什么是这样?是否有办法解决此问题,而不使用原始类型? 问题答案: 尝试 注意:请注意,当您使用类似List的集合时,您只能在“只读”模式下使用它(添加空值除外)。
问题内容: 我对Java泛型中的嵌套嵌套通配符有疑问。 这是一个常见的情况: 这是标准的Java泛型,工作正常。 但是,如果通配符嵌套,它将不再起作用: 这会导致编译器错误。 我已经尝试了各种强制类型转换和通配符置换,但是无法正常工作。我不记得以前曾见过此问题,并且我使用泛型已有多年。我是否太累了,缺少明显的东西? 问题答案: 所以问题是,可以实现为: 您需要确定您的实际意思。 大概是这样的:
目前我有这个阵列= 条件: 如果每个嵌套数组index2都相同,那么我想用[0.0 1.0,1.0 2.0,2.0 3.0,3.0 4.0] = [1.0,3.0,5.0,7.0]来求和 我想要的最终结果:[[“efg”, [1.0, 3.0, 5.0, 7.0], “测试”]] 有什么方法或建议来获得这个结果吗?
问题内容: 这样编译(1.6) 但这不是 的错误 有人可以解释为什么吗?谢谢 编辑:编辑为结果 问题答案: 因为这会破坏类型安全性:
问题内容: 在以下示例中: 为什么对second(b)的调用有效,但对third(a)的调用却无效 ? 我收到以下错误: 问题答案: 如果您希望能够使用自变量进行调用,则需要将签名更改为此: 将上面的工作,因为不像,是兼容。这样想: 推理很简单。如果你有 然后,如果您 可以这样 调用该方法:
问题内容: 我想在我的api中提供以下内容: 所以我这样写: 但是java无法解决。 随着代替它的工作原理,但第二个实际上是多余的“事业AbtractThing已定义的类型。所以我喜欢摆脱它。 问题答案: 你不能摆脱它。第二个不是多余的。您希望编译器将第一个解释为类型参数,但事实并非如此。您也可以这样写: 请注意,在这种情况下,它是一个具体的类,而不是类型参数。将此与以下内容进行比较: 请注意,它