我想用另一种字体制作一种字体。这就是我想要做的事情:
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
我不知道!
符号的含义和通配符星号符号的含义。这是什么意思?
答案 0 :(得分: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 :(得分:1)
我在Kotlin文档中查找了Star Projections,并且从快速阅读中可以看出,这是Kotlin将方差引入泛型类型的方式,所以*
中的星号out
{1}}位置表示out Any?
,因此我将代码更改为此代码并且有效:
val attributesMap : Map<TextAttribute, Any?> = font.getAttributes();
val attributes : MutableMap<TextAttribute, Any?> =
attributesMap as MutableMap<TextAttribute, Any?>;
还有我使用的编译时类型是只读接口kotlin.collections.Map<K, V>
,因为我正在将项目放入其中。但这是我注意到的事情,并且一旦我摆脱了前一行中的投射错误就要照顾好。