我想用另一种字体制作一种字体 . 这是我想要做的:
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 回答
第一个问题是getAttributes方法返回一个可以保存空值的映射,而
Map<TextAttribute, Any>
声明它的值不能为空 . 第二个问题是Kotlin中的Map接口不允许变异 .要解决这些问题,请将代码更改为:
甚至更简洁:
最后,由于Kotlin有方便的扩展方法,整个字体修改可以变成:
我在Kotlin文档中查找了Star Projections,并且从快速阅读中看来,Kotlin将方差引入泛型类型的方式似乎是
out
位置的星号*
,所以我将代码更改为此并且它有效:而且我使用的编译时类型是一个只读接口
kotlin.collections.Map<K, V>
,因为我正在将项目放入其中 . 但这是我注意到的事情,并且一旦我摆脱了前一行中的投射错误就要照顾好了 .