我必须分配什么编译时types才能获得java.util.Map的返回值

我想从另一个字体派生出一个字体。 这是我想要做的:

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

但是,Kotlin编译器在这一行上抱怨:

 val attributes : Map = font.getAttributes(); 

随着消息:

  Type mismatch: inferred type is (Mutable)Map! but Map was expected 

根据我对Javagenerics的有限理解,我知道font.getAttributes()返回一个java.util.Map ; 后一种types的参数意味着当你从这个映射中创建一个有界/关闭的genericstypes时,请指定作为第二个types参数的任何扩展java.lang.Object的东西

所以,当我首先尝试了以下几行:

 val attributes : java.util.Map = font.getAttributes(); 

Kotlin编译器说:

这个类不应该在Kotlin中使用。 改为使用kotlin.collections.Map或kotlin.collections.MutableMap。

还说:

  Type mismatch: inferred type is (MutableMap..kotlin.collections.Map?) but java.util.Map was expected 

我不知道是什么! 符号表示和通配符星号符号的意思。 这是什么意思?

第一个问题是getAttributes方法返回一个可以包含null的映射,而Map声明它的值不能为null。 第二个问题是Kotlin中的Map接口不允许突变。

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

 val attributes : Map = 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)) } 

我在Kotlin文档中查找了Star Projections ,从快速阅读中可以看出,这是Kotlin向generics引入差异的方式,所以outout中的星号*意味着out Any? ,所以我改变了我的代码,它工作:

 val attributesMap : Map = font.getAttributes(); val attributes : MutableMap = attributesMap as MutableMap; 

还有,我使用的编译时types是一个只读接口kotlin.collections.Map ,因为我正在把项目放入它。 但那是我注意到的,并且一旦我摆脱了前一行中的铸造错误,就要照顾好了。