Иногда при преобразовании байтов в целые числа требуется & 0xFF, но я не считаю это проблемой.
Почему нет? Является ли «применение побитового И с 0xFF» частью того, что пытается представить ваш код? Если нет, то почему это должно быть частью того, что вы написали? На самом деле я обнаружил, что почти все, что я хочу сделать с байтами, кроме простого копирования их из одного места в другое, требует маски. Я хочу, чтобы мой код не содержал мусора; этому мешает отсутствие беззнаковых байтов :(
Кроме того, рассмотрите API, который всегда возвращает неотрицательное значение или только принимает неотрицательные значения. Использование беззнакового типа позволяет вам выразить это ясно, без необходимости проверки. Лично я считаю позором, что неподписанные типы не используются больше в .NET, например. для таких вещей, как String.Length
, ICollection.Count
и т. д. Очень часто значение, естественно, может быть только неотрицательным.
Является ли отсутствие беззнаковых типов в Java фатальным недостатком? Явно нет. Это раздражает? Абсолютно.
Комментарий, который вы цитируете, бьет в самую точку:
Отсутствие в Java неподписанных типов данных также противоречит этому. Да, вы можете обойти это, но это не идеально, и вы будете использовать код, который на самом деле неправильно отражает базовые данные.
Предположим, вы взаимодействуете с другой системой, которой требуется 16-битное целое число без знака, и вы хотите представить число 65535. Вы утверждаете, что «данные — это просто биты, поэтому я не вижу здесь проблемы». " - но необходимость передать -1 для обозначения 65535 является проблемой. Любое несоответствие импеданса между представлением ваших данных и их основным значением вносит дополнительный скачок скорости при написании, чтении и тестировании кода.
Вместо этого мне проще, что мне не нужно рассматривать операции между беззнаковыми и подписанными числами и преобразования между ними.
Единственные случаи, когда вам нужно рассматривать эти операции, — это когда вы, естественно, работали со значениями двух разных типов — со знаком и без знака. В этот момент вы абсолютно хотите, чтобы это различие было указано. Поскольку знаковые типы используются для представления беззнаковых значений, вы должны по-прежнему учитывать различия, но тот факт, что вы должны это делать, скрыт от вас. Рассмотреть возможность:
// This should be considered unsigned - so a value of -1 is "really" 65535
short length = /* some value */;
// This is really signed
short foo = /* some value */;
boolean result = foo < length;
Предположим, что foo
равно 100, а length
равно -1. Каков логический результат? Значение length
представляет 65 535, поэтому логически foo
меньше его. Но вы, вероятно, согласитесь с приведенным выше кодом и получите неправильный результат.
Конечно, здесь даже не нужно представлять различные типы. Оба они могут быть естественными значениями без знака, представленными в виде значений со знаком, где отрицательные числа логически больше положительных. Применяется та же ошибка, и не было бы проблемы, если бы у вас были беззнаковые типы в языке.
Вы также можете прочитать это интервью с Джошуа Блохом (кэш Google, насколько я полагаю, его больше нет на java.sun.com), в том числе:
О, хороший вопрос... Я хочу сказать, что самое странное в платформе Java — это то, что тип байта подписан. Я никогда не слышал объяснения этому. Это довольно нелогично и вызывает всевозможные ошибки.
person
Jon Skeet
schedule
05.04.2012
/
,%
,<
и>
имеют разные интерпретации для значений со знаком и без знака. - person Louis Wasserman   schedule 05.04.2012