有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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) 个答案

  1. # 1 楼答案

    这就是当您传递不一致的方法参数时,编译器推断类型参数的方式。 如果您注意到,^{}方法对DateInteger使用相同的类型参数K。有人会认为这应该失败,因为我们传递的是不一致的方法参数,这意味着我们传递的是同一类型参数K的不同类型。但令人惊讶的是,事实并非如此

    Class<Date>Class<Integer>可转换为以下所有功能:

    • Class<? extends Object>
    • Class<? extends Serializable>
    • Class<? extends Comparable<?>>

    因此,类型K被推断为所有类型的混合:

    K := Class<? extends Object&Serializable&Comparable<?>>
    

    这就是该方法的返回值:

    ImmutableMap<Class<? extends Object&Serializable&Comparable<?>>, String>
    

    当然,您不能直接将其分配给ImmutableMap<Class<?>, String>,因为它们是不兼容的类型。还要注意的是,不能像上面那样显式地声明映射,因为不能为通配符指定多个边界。这只是编译器推断类型的方式

    对于这些类型的情况,如果编译器无法按照您的要求正确推断类型参数,您可以在方法调用时传递显式类型参数,这是您上次尝试时所做的:

    ImmutableMap<Class<?>, String> map = ImmutableMap.<Class<?>, String>of( 
        Integer.class, "Integer", 
        Date.class, "Date" 
    );
    

    这现在可以工作了,因为编译器从显式类型参数中知道返回值的类型为-ImmutableMap<Class<?>, String>

    Oddly enough it does work if I add a cast to Class<?> to any(!) of the keys

    只要您将任何元素类型强制转换为Class<?>,因为Class<?>表示Class<T>的所有实例的族,因此它是所有Class实例的公共超类型。因此,类型参数将自动推断为Class<?>。这样就行了