Ich habe ein folgendes Code-Snippet in Kotlin:
%Vor%Es schlägt in der zweiten Zeile mit der folgenden Ausnahme fehl, wenn ich versuche, es auszuführen:
java.lang.ClassCastException: java.lang.Character kann nicht in java.lang.Number umgewandelt werden
IDE (IntelliJ) beschwert sich nicht über einen falschen Typ. Das Problem hängt irgendwie damit zusammen, dass Chars von Pair<Char, Char>
kommen, weil 'z'.compareTo('z')
gut funktioniert. Weißt du, wie Kotlin den folgenden Anruf löst?
Ich benutze Kotlin 1.0.4
TL; DR Scheinbar ist dies ein Compiler-Bug.
Der Grund für dieses Verhalten liegt im Bytecode, den der Kotlin-Compiler für diese beiden Aufrufe generiert. (Wenn Sie IntelliJ IDEA verwenden, können Sie den Bytecode mit dem Bytecode-Anzeige-Tool untersuchen).
Erstens ist der Bytecode, der für den Aufruf 'z'.compareTo('z')
generiert wurde:
Es heißt kotlin.jvm.internal.Intrisics.compare()
, die zwei Int
s vergleicht, und die Char
s werden direkt als Int
s in den Stack geschoben ( BIPUSH
bedeutet Push-Byte als ganze Zahl ).
Aber wenn Sie sich den Bytecode für pair.first.compareTo(pair.second)
ansehen, werden Sie folgendes finden:
Es ruft auch kotlin.jvm.internal.Intrisics.compare
auf, aber hier ist, was es vorher versucht hat:
ALOAD 1
und INVOKEVIRTUAL ...
) Number
( CHECKCAST ...
) java.lang.Number.intValue()
( INVOKEVIRTUAL ...
) Die zweite und die dritte Zeile sind die Schuldigen, Char
ist kein Number
. Es sieht einfach so aus, als ob der Compiler für diesen Vergleich einen inkorrekten Bytecode erzeugt hätte (das wäre korrekt für die Number
-Typen, scheint aber, dass Char
nicht separat behandelt wird).
Es gibt ein Problem im Kotlin Issue Tracker, das wahrscheinlich in zukünftigen Versionen behoben wird.
Um den Aufruf in Ihrem Code zu fixieren, können Sie die Char
s vor dem Aufruf manuell konvertieren:
Tags und Links kotlin