首页 文章

必须分配什么编译时类型来接收java.util.Map <TextAttribute,?>的返回值

提问于
浏览
1

我想用另一种字体制作一种字体 . 这是我想要做的:

val font : Font = this.label.getFont();
val attributes : Map<TextAttribute, Any> = font.getAttributes();
attributes.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
this.label.setFont(font.deriveFont(attributes));

然而,Kotlin编译器在线上抱怨:

val attributes : Map<TextAttribute, Any> = font.getAttributes();

随着消息:

Type mismatch: inferred type is 
(Mutable)Map<TextAttribute!, *>! but 
Map<TextAttribute, Any> was expected

根据我对Java中泛型的有限理解,我理解font.getAttributes()返回 java.util.Map<TextAttribute, ?> ;后一个类型参数意味着当您从此映射中创建有界/闭合泛型类型时,请指定扩展java.lang.Object的任何内容作为第二个类型参数 .

所以,当我第一次尝试使用以下行时:

val attributes : java.util.Map<TextAttribute, Object> = font.getAttributes();

Kotlin编译器说:

此类不应在Kotlin中使用 . 请改用kotlin.collections.Map或kotlin.collections.MutableMap .

它还说:

Type mismatch: inferred type is 
 (MutableMap<TextAttribute!, *>..kotlin.collections.Map<TextAttribute!, *>?) 
 but java.util.Map<TextAttribute, Object> was expected

我不知道 ! 符号的含义和通配符星号符号的含义 . 这是什么意思?

2 回答

  • 3

    第一个问题是getAttributes方法返回一个可以保存空值的映射,而 Map<TextAttribute, Any> 声明它的值不能为空 . 第二个问题是Kotlin中的Map接口不允许变异 .

    要解决这些问题,请将代码更改为:

    val attributes : Map<TextAttribute, *> = font.getAttributes();
    val updatedAttributes = attributes.plus(TextAttribute.UNDERLINE to TextAttribute.UNDERLINE_ON)
    

    甚至更简洁:

    val updatedAttributes = font.attributes.plus(TextAttribute.UNDERLINE to TextAttribute.UNDERLINE_ON)
    

    最后,由于Kotlin有方便的扩展方法,整个字体修改可以变成:

    label.font = label.font.run { 
        deriveFont(attributes.plus(TextAttribute.UNDERLINE to TextAttribute.UNDERLINE_ON)) 
    }
    
  • 1

    我在Kotlin文档中查找了Star Projections,并且从快速阅读中看来,Kotlin将方差引入泛型类型的方式似乎是 out 位置的星号 * ,所以我将代码更改为此并且它有效:

    val attributesMap : Map<TextAttribute, Any?> = font.getAttributes();
    val attributes : MutableMap<TextAttribute, Any?> = 
          attributesMap as MutableMap<TextAttribute, Any?>;
    

    而且我使用的编译时类型是一个只读接口 kotlin.collections.Map<K, V> ,因为我正在将项目放入其中 . 但这是我注意到的事情,并且一旦我摆脱了前一行中的投射错误就要照顾好了 .

相关问题