Котлин чар сравнениедля не
у меня есть следующий фрагмент кода в Котлин:
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
С толкнул в стек прямо как Int
s (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 исправьте вызов в своем коде сейчас, вы можете преобразовать Char
s вручную перед вызовом:
pair.first.toInt().compareTo(pair.second.toInt())