Does java.util.HashMap не реализует java.util.Map в Котлине?
Мне трудно понять, почему Java HashMap
несовместим с Java Map
в Kotlin:
val map : java.util.Map<Int, Int> = java.util.HashMap<Int, Int>()
// ERROR: Type mismatch
Является ли это ошибкой или преднамеренно принуждается быть ошибкой в Kotlin?
Вот второй пример с компилятором Java в Kotlin. Взгляните на этот файл примера Java:
public class Test {
public static void main(String[] args) {
java.util.Map<Integer, Integer> map = new java.util.HashMap<>();
insertValue(map);
}
private static void insertValue(java.util.Map<Integer, Integer> map) {
map.putIfAbsent(0, 1);
}
}
Запуск "Convert Java to Kotlin" приводит к этому файлу:
object Test {
@JvmStatic fun main(args: Array<String>) {
val map = java.util.HashMap<Int, Int>()
insertValue(map)
}
private fun insertValue(map: Map<Int, Int>) {
map.putIfAbsent(0, 1) // ERROR! Unresolved reference
}
}
Если я попытаюсь изменить его, чтобы больше отразить исходный файл, где insertValue
ожидал Java java.util.Map
, я получаю еще одну ошибку:
object Test {
@JvmStatic fun main(args: Array<String>) {
val map = java.util.HashMap<Int, Int>()
insertValue(map) // ERROR: Type mismatch
}
private fun insertValue(map: java.util.Map<Int, Int>) {
map.putIfAbsent(0, 1) // is now OK
}
}
Ответы
Ответ 1
В Kotlin a java.util.HashMap
во время компиляции не реализует java.util.Map
, а реализует kotlin.collections.MutableMap
, который расширяет только для чтения kotlin.collections.Map
.
Это связано с тем, что Kotlin отображает типы. Подробнее см. Коллекции в Kotlin M3 is Out!.
MutableMap
не определяет putIfAbsent
, но имеет функцию расширения getOrPut
.
Ответ 2
Я создал отчет об ошибке, прежде всего для конвертера "Java to Kotlin", который генерирует неверный код Kotlin в моем исходном примере:
KT-10400 Конвертер Java в Kotlin: преобразование кода Java, к которому обращается java.util.HashMap через интерфейс java.util.Map
Я также упомянул, что java.util.HashMap
не реализует java.util.Map
, но я оставляю его разработчикам Kotlin, чтобы решить, является ли это ошибкой или подходит ли компилятор, чтобы отклонить его.
ОБНОВЛЕНИЕ: Ошибка помечена как разрешенная (commit 5e231db6).
Ответ 3
Я думаю, это ошибка. Вы можете сообщить об этом там
https://youtrack.jetbrains.com/issues/KT
Но тем не менее, putIfAbsent
- это функция Java 8, еще не поддерживаемая в интерфейсе Kotlin (MutableMap
отсутствует этот метод).