Frage

Wenn Sie Variablen vom Typ Byte oder kurz und versuchen zu erklären arithmetische Operationen auf diese ausführen, erhalten Sie den Fehler „Typenkonflikt: nicht int zu kurz konvertieren“ (oder entsprechend „Typenkonflikt: kann int Byte nicht konvertieren“).

byte a = 23;
byte b = 34;
byte c = a + b;

In diesem Beispiel wird der Compiler-Fehler ist in der dritten Zeile.

War es hilfreich?

Lösung

Auch wenn die arithmetischen Operatoren definiert sind, auf beliebigen numerischen Typ zu arbeiten, die Java-Sprachspezifikation nach (5.6.2 Binary Numeric Promotion), Operanden vom Typ Byte und Kurz werden automatisch, bevor sie Hand an die Betreiber auf int gefördert.

Um arithmetische Operationen auf Variablen vom Typ Byte oder kurz auszuführen, müssen Sie den Ausdruck in Klammern (innerhalb derer Operationen als Typ int durchgeführt wird) umschließen, und dann das Ergebnis zurückgeworfen auf den gewünschten Typ.

byte a = 23;
byte b = 34;
byte c = (byte) (a + b);

Hier ist eine Follow-on-Frage an den realen Java-Gurus: warum? Die Typen Byte und kurz sind völlig in Ordnung numerische Typen. Warum Java erlaubt keine direkte arithmetische Operationen auf diese Art? (Die Antwort ist nicht „Verlust der Genauigkeit“, da es kein ersichtlicher Grund ist in erster Linie zu konvertieren in int.)

Update: jrudolph schlägt vor, dass dieses Verhalten auf die Vorgänge in der JVM basiert, speziell, dass nur Voll- und Doppelwort Betreiber umgesetzt werden. Daher an Betreiber auf Bytes und Shorts, müssen sie in int umgewandelt werden.

Andere Tipps

Die Antwort auf Ihre Folgefrage ist hier:

  

Operanden vom Typ Byte und Kurz werden automatisch an die Betreiber vor dem geben int gefördert

Also, in Ihrem Beispiel a und b sind beide mit einem int umgewandelt, bevor sie an den Operator + übergeben wird. Das Ergebnis der Addition von zwei ints zusammen ist auch ein int. Der Versuch, dann, dass int zu einem byte Wert zuweisen verursacht den Fehler, weil es ein möglicher Verlust an Präzision ist. Durch die explizite das Ergebnis Gießen Sie den Compiler sagen: „Ich weiß, was ich tue“.

Ich denke, die Sache ist, dass die JVM nur zwei Typen von Stack-Wert unterstützt: Wort Größe und Doppelwort Größe.

Dann entschied sie wahrscheinlich, dass sie nur eine Operation brauchen würde, die auf Wort große Zahlen auf dem Stack arbeitet. Es gibt also nur iadd, IMUL und so weiter auf Bytecode-Ebene (und keine Operatoren für Bytes und Shorts).

So Sie einen int-Wert als das Ergebnis dieser Operationen erhalten, die Java kann sicher nicht auf den kleineren Byte konvertieren zurück und kurze Datentypen. So zwingen sie Sie werfen den Wert zu verengen wieder auf Byte / kurz.

Aber am Ende haben Sie Recht: Dieses Verhalten ist auf das Verhalten von ints nicht konsistent, zum Beispiel. Sie können problemlos zwei Ints hinzufügen und keine Fehlermeldung erhalten, wenn das Ergebnis überläuft.

Die Java-Sprache immer Argumente von arithmetischen Operatoren fördert in int, long, float oder double. So nehmen Sie den Ausdruck:

a + b

wobei a und b vom Typ Byte sind. Dies ist eine Abkürzung für:

(int)a + (int)b

Dieser Ausdruck ist vom Typ int. Es macht deutlich Sinn, einen Fehler zu geben, wenn einen int Wert auf einen Byte-Variable zugewiesen wird.

Warum sollte die Sprache auf diese Weise definiert werden? Angenommen, war ein 60 und b 70 war, dann a + b ist -126 - Ganzzahlüberlauf. Im Rahmen eines komplizierteren Ausdrucks, der in einem int führen wurde erwartet, kann dies ein schwieriger Fehler worden. Beschränken Verwendung von Byte und kurz Array Speicherung, Konstanten für Dateiformate / Netzwerkprotokolle und Puzzler.

Es gibt eine interessante Aufnahme von Javapolis 2007. James Gosling ist ein Beispiel, wie kompliziert unsigned-Arithmetik zu geben (und warum es nicht in Java). Josh Bloch weist darauf hin, dass sein Beispiel auch das falsche Beispiel unter normalen unterzeichnet Arithmetik gibt. Aus verständlicher Arithmetik, müssen wir mit beliebiger Genauigkeit.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top