Котлин чар сравнениедля не
у меня есть следующий фрагмент кода в Котлин:
val pair: Pair<Char,Char> = 'z' to 'z'
val comparison = pair.first.compareTo(pair.second)
println(comparison)
он терпит неудачу во второй строке со следующим исключением, когда я пытаюсь запустить его:
java.ленг.ClassCastException: java.ленг.Символ не может быть приведен к java.ленг.Номер
IDE (IntelliJ) не жалуется на неправильный тип. Проблема как-то связана с тем, что символы исходят от Pair<Char, Char>, потому что 'z'.compareTo('z') работает нормально. Знаете ли вы, как Котлин решает после звонка?
Я использую Kotlin 1.0.4
1 ответов
TL; DR по-видимому, это ошибка компилятора.
причина такого поведения заключается в байт-коде, который компилятор Kotlin генерирует для этих двух вызовов. (Если вы используете IntelliJ IDEA, вы можете проверить байт-код с помощью инструмент просмотра байт-кода).
во-первых, байт-код, созданный для 'z'.compareTo('z') звонок:
LINENUMBER 10 L3
BIPUSH 122
BIPUSH 122
INVOKESTATIC kotlin/jvm/internal/Intrinsics.compare (II)I
он называет kotlin.jvm.internal.Intrisics.compare() что сравнивает два Intи CharС толкнул в стек прямо как Ints (BIPUSH означает push byte как целое число).
но если вы посмотрите на байт-код для pair.first.compareTo(pair.second), вы найдете что-то вроде этого:
ALOAD 1
INVOKEVIRTUAL kotlin/Pair.getFirst ()Ljava/lang/Object;
CHECKCAST java/lang/Number
INVOKEVIRTUAL java/lang/Number.intValue ()I
ALOAD 1
INVOKEVIRTUAL kotlin/Pair.getSecond ()Ljava/lang/Object;
CHECKCAST java/lang/Number
INVOKEVIRTUAL java/lang/Number.intValue ()I
INVOKESTATIC kotlin/jvm/internal/Intrinsics.compare (II)I
он называет kotlin.jvm.internal.Intrisics.compare тоже, но вот что он пытается сделать раньше:
- получить компонент из пары (
ALOAD 1иINVOKEVIRTUAL ...строки) - проверяем, что объект может быть приведен к
Number(CHECKCAST ...) - принять
java.lang.Number.intValue()(INVOKEVIRTUAL ...)
вторая и третья строки являются виновником,Char - это не Number. Просто похоже, что компилятор сгенерировал неправильный байт-код для этого сравнения (это было бы правильно для Number типы, вроде Char просто не обрабатывается отдельно).
здесь вопрос о в трекере проблем Kotlin он, вероятно, будет исправлен в будущих выпусках.
To исправьте вызов в своем коде сейчас, вы можете преобразовать Chars вручную перед вызовом:
pair.first.toInt().compareTo(pair.second.toInt())