我定义了这个类:
class NeverNullMap<K, V>(private val backing: MutableMap<K, V> = mutableMapOf(), val default: () -> V): MutableMap<K, V> by backing {
override operator fun get(key: K): V = backing.getOrPut(key, default)
}
我可以像这样完美地使用它:
fun main(args: Array<String>) {
val myMap = NeverNullMap<String, Int> {0}
println(myMap["test"])
myMap["test"] = myMap["test"] + 10
println(myMap["test"])
}
正如预期的那样,输出是:
0
10
但是当我尝试将其更改为:
fun main(args: Array<String>) {
val myMap = NeverNullMap<String, Int> {0}
println(myMap["test"])
myMap["test"] += 10
println(myMap["test"])
}
I get:
Exception in thread "main" java.lang.IllegalAccessError: tried to access method kotlin.collections.MapsKt__MapsKt.set(Ljava/util/Map;Ljava/lang/Object;Ljava/lang/Object;)V from class Day08Kt
at Day08Kt.main(Day08.kt:10)
为什么会发生这种情况?
Edit:
深入研究一下反编译的代码,它们都会被编译成完全不同的代码。
在没有的工作版本中+=
它被编译为:
Map var2 = (Map)myMap;
String var3 = "test";
Integer var4 = ((Number)myMap.get("test")).intValue() + 10;
var2.put(var3, var4);
非工作版本被编译为:
MapsKt.set(myMap, "test", ((Number)myMap.get("test")).intValue() + 10);
所以它调用这个函数:https://github.com/JetBrains/kotlin/blob/1.2.0/libraries/stdlib/src/kotlin/collections/Maps.kt#L175 https://github.com/JetBrains/kotlin/blob/1.2.0/libraries/stdlib/src/kotlin/collections/Maps.kt#L175
我仍然不知道为什么会产生错误,只是为什么第一个版本的行为不同。
Edit: YouTrack 报告链接 https://youtrack.jetbrains.com/issue/KT-21724