unsigned bytes in Java
Donnerstag, 22. Februar 2007Arbeitet man in Java mit dem Datentyp byte, so stellt man ein merkwürdiges Verhalten fest. Liest man nun beispielsweise eine Datei als byte[]-Array ein und lässt sich die eingelesenen Bytes anzeigen, so findet man neben typischen Bytes wie 0x20 (Leerzeichen) oder 0x41 (”A“) auch plötzlich Werte wie 0xffffffc4 (Ä) und 0xffffff87 (‡). Das sind Werte, die doch gar nicht in ein Byte passen?!
Die Ursache ist, dass Java keine vorzeichenlosen Datentypen kennt (also auch keine "unsigned" byte) und daher alle Bytes mit einem Wert über 0x7f als negative Bytes interpretiert. Da Java nun auch intern die Datentypen byte, short und int in vier Bytes speichert, wird das “Vorzeichen” gemäß binärer Arithmetik nach vorne verlängert. So kommen die überlangen Bytes zustande.
Zusätzlich beschwert sich Java aufgrund dieser Tatsache auch, wenn man Werte größer als 0x7f in einem byte speichern möchte. Das erzeugt den Fehler (keine Warnung, was vielleicht angebrachter wäre): possible loss of precision! Umgehen kann man diese Fehlermeldung nur, indem man den Wert explizit auf byte castet.
jGuru empfiehlt sogar, auf die Verwendung der kleinen Datentypen zu verzichten und gleich mit int zu arbeiten, wenn man “vorzeichenlos” arbeiten möchte. Da der Speicherverbrauch der gleiche ist, kann man die Problematik damit elegant umgehen — wenn man nicht gezwungen ist, mit byte zu arbeiten ;)