java问题使用类创建ImmutableMap<?>作为关键
我试图创建一个ImmutableMap
来将类映射到字符串(注意:这当然只是一个示例!)。然而
ImmutableMap<Class<?>, String> map = ImmutableMap.of(
Integer.class, "Integer",
Date.class, "Date"
);
给了我以下的错误
Type mismatch: cannot convert from ImmutableMap<Class<? extends Object&Comparable<?>&Serializable>,String> to ImmutableMap<Class<?>,String>
奇怪的是,如果我在任何(!)的Class<?>
中添加一个cast,它确实会起作用钥匙的数量,即
ImmutableMap<Class<?>, String> map = ImmutableMap.of(
Integer.class, "Integer",
Date.class, "Date",
(Class<?>) String.class, "String",
long.class, "Long"
);
很好用。我对这种行为有点困惑:首先,为什么没有演员阵容它就不能工作?所有这些都是类,它真的没有比Class<?>
更通用的了,那么为什么它不工作呢?其次,为什么任何一把钥匙上的石膏都能起作用
(旁注:如果你想知道我为什么要做这样的事——是的,这是因为思考……)
编辑:我实际上刚刚意识到这是可行的,但我仍然想了解上述行为
ImmutableMap<Class<?>, String> map = ImmutableMap.<Class<?>, String>builder()
.put( Integer.class, "Integer" )
.put( Date.class, "Date" )
.build();
# 1 楼答案
这就是当您传递不一致的方法参数时,编译器推断类型参数的方式。 如果您注意到,^{} 方法对
Date
和Integer
使用相同的类型参数K
。有人会认为这应该失败,因为我们传递的是不一致的方法参数,这意味着我们传递的是同一类型参数K
的不同类型。但令人惊讶的是,事实并非如此Class<Date>
和Class<Integer>
可转换为以下所有功能:Class<? extends Object>
Class<? extends Serializable>
Class<? extends Comparable<?>>
因此,类型
K
被推断为所有类型的混合:这就是该方法的返回值:
当然,您不能直接将其分配给
ImmutableMap<Class<?>, String>
,因为它们是不兼容的类型。还要注意的是,不能像上面那样显式地声明映射,因为不能为通配符指定多个边界。这只是编译器推断类型的方式对于这些类型的情况,如果编译器无法按照您的要求正确推断类型参数,您可以在方法调用时传递显式类型参数,这是您上次尝试时所做的:
这现在可以工作了,因为编译器从显式类型参数中知道返回值的类型为-
ImmutableMap<Class<?>, String>
只要您将任何元素类型强制转换为
Class<?>
,因为Class<?>
表示Class<T>
的所有实例的族,因此它是所有Class
实例的公共超类型。因此,类型参数将自动推断为Class<?>
。这样就行了