отрицательный символ Значение JAVA

Почему это происходит следующим образом:

char p = 0; p--; System.out.println(p); 

результат 65535

Почему не выдают ошибку компиляции или исключение времени выполнения? Я ожидал, что это не может быть отрицательным. Вместо этого он начинает отсчет с ног на голову. Заранее спасибо.

Почему не выдают ошибку компиляции или исключение времени выполнения?

Поскольку спецификация языка требует, чтобы арифметика на примитивных типах была по модулю 2^width , поэтому -1 становится 2^16-1 .

В разделе о целых операциях указано, что

Встроенные целочисленные операторы не указывают на переполнение или недополнение.

так что запрещает бросать исключение.

Для используемого оператора постфикса-декремента его поведение указано в 15.14.3

В противном случае значение 1 вычитается из значения переменной, и разница сохраняется в переменной. Перед вычитанием выполняется двоичное числовое продвижение (§5.6.2) на значение 1 и значение переменной. При необходимости различие сужается сужением примитивного преобразования (п. 5.1.3) и / или подвергается конверсии бокса (п. 5.1.7) к типу переменной до ее сохранения. Значение выражения постфиксного декремента – это значение переменной перед сохранением нового значения.

Двоичное числовое продвижение преобразует как значение, так и значение 1 в int (поскольку тип здесь – char ), таким образом, у вас есть промежуточный результат -1 как int , тогда выполняется сужение примитивного преобразования:

Сужение преобразования целого числа со знаком в интегральный тип T просто отбрасывает все, кроме n бит младшего разряда, где n – количество бит, используемых для представления типа T. В дополнение к возможной потере информации о величине числового значения , это может привести к тому, что знак результирующего значения будет отличаться от знака входного значения.

что приводит к значению char 0xFFFF (поскольку Java указывает представление 0xFFFF представления для его знаковых целых типов, явно указанных в спецификации унарного минуса ):

Для целых значений отрицание совпадает с вычитанием из нуля. Язык программирования Java использует представление двух дополнений для целых чисел , а диапазон значений двух дополнений не является симметричным, поэтому отрицание максимального отрицательного int или long приводит к тому же максимальному отрицательному числу. В этом случае происходит переполнение, но исключение не генерируется. Для всех целых значений x, -x равно (~ x) +1.

Для общего поведения обхода для результатов вне диапазона в качестве примера в спецификации оператора умножения :

Если целочисленное умножение переполняется, то результатом являются младшие биты математического произведения, представленные в некотором достаточно большом формате с двумя дополнениями. В результате, если происходит переполнение, знак результата может быть не таким, как знак математического произведения двух значений операнда.

Подобные фразы встречаются в спецификации целочисленного сложения, и для выполнения a - b == a + (-b) требуется вычитание, поэтому последует поведение переполнения.

Потому что именно так определяется язык Java. Время выполнения не проверяет границы при каждой операции (вероятно, потому, что это будет чрезвычайно дорого). Он просто переполняется или переполняется.

  • javafx, используя объекты MainController или других controllerов в соответствующем classе controllerа
  • --add-модули только при компиляции
  • Spring + Hibernate: другой объект с тем же значением идентификатора уже был связан с сеансом
  • Получение исключения ConcurrentModificationException при удалении элемента из java.util.List во время итерации списка?
  • addKeyListener () не работает для JPanel
  • Получение списка контактов из hotmail gmail yahoo в java?
  • Поиск в ArrayList с пользовательскими объектами для определенных строк
  • Как вручную принудительно совершить фиксацию в методе @Transactional?
  • Как загрузить файлы на серверной папке с помощью jsp
  • Качание на OSX: как ловушка command-Q?
  • Как использовать class в Java?
  • Давайте будем гением компьютера.