TL; DR顯然,這是一個編譯器錯誤。
此行爲的原因在於Kotlin編譯器爲這兩個調用生成的字節碼。 (如果您使用IntelliJ IDEA,則可以使用the bytecode viewing tool檢查字節碼)。
首先,對於'z'.compareTo('z')
呼叫產生的字節碼是:
LINENUMBER 10 L3
BIPUSH 122
BIPUSH 122
INVOKESTATIC kotlin/jvm/internal/Intrinsics.compare (II)I
它調用kotlin.jvm.internal.Intrisics.compare()
比較兩個Int
s,並且Char
s的被推送到堆棧直接作爲Int
S(BIPUSH
裝置推字節整數)。
但如果你看看字節碼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
也是如此,但在這裏就是它試圖做之前:
第二和第三線的罪魁禍首,Char
不是Number
。它看起來就像是編譯器爲這個比較生成了不正確的字節碼(這對於Number
類型來說是正確的,看起來像Char
只是沒有單獨處理)。
Kotlin問題跟蹤器中有an issue about this,它可能會在將來的版本中修復。
要修復代碼中的呼籲,現在,我們也可以將Char
s的電話之前手動:
pair.first.toInt().compareTo(pair.second.toInt())