[Чтение скорости прохождения -1] a = a + b и a + = b различия

Java задняя часть переводчик Android

предисловие

Скорочтение коротких текстов, это будет цикл статей. Я сам написал и прочитал много статей. Я обнаружил, что многие из них представляют собой сборники, а не сериалы. Конечно, когда у меня будет время, я действительно найду сборники статей и хорошо их изучу. Но большинство статей словно тонет в море и теряет свою ценность.

Поэтому родилась идея этой серии.Характеристики серии статей: взять за основу какие-то базовые знания в ежедневной разработке, и обернуть вокруг этого понятный текст. Попробуйте рассказать часть знаний в режиме меньшего размышления. Давайте на самом деле узнаем что-то в разрозненное время!

Эйнштейн: «Если вы не можете что-то просто объяснить, вы на самом деле этого не понимаете».

[Скорочтение короткого текста-1] Разница между a=a+b и a+=b

[Короткое чтение скорости текста-2] Перегрузка/перезапись, динамическая/статическая диспетчеризация? (повторно)

[Скорочтение короткого текста-3] Почему внутренний анонимный класс должен использовать внешние переменные для добавления окончательного

[Короткая скорость текста-4] Будет ли новый подкласс создавать экземпляр родительского класса?

[Краткое чтение скорости текста -5] Введение в многопоточное программирование: процесс, поток, безопасность потока

Внешний вид роль

маленький А: Только начинаю программировать на Java...

MDove: Android-разработчик, который почти не может есть...

основная тема

маленький А:MDove, недавно у меня возник немного незрелый вопрос, не знаю говорить или нет.

MDove: Не спрашивай, незрелый ли ты...

маленький А: Сумма неправильная, сумма действительно неправильная. Э-э, вам никогда не следует изучать Java в первую очередь...

MDove: спрашивай, спрашивай, спрашивай...

маленький А: а=а+b и а+=b. В чем разница между ними? разницы не вижу!

MDove: То, что ты сказал, не имеет значения, не так ли?

int a = 1;
int b = 2;
a = a + b;
a += b;

MDove: Тогда вы изменили способ написания? Например, измените тип b:

float b = 2F;

MDove: Как насчет этого, я вижу эффект. Не видел? ? Хорошо, тогда я вставлю эффект:

编译不能通过

MDove: Это проясняет, верно? b после продвижения типа. найдуa = a + bНет возможности его скомпилировать, нужно принудительно преобразовать тип. но нашa + = bНо да, почему так? это на самом деле очень легко. Давайте декомпилируем этот файл класса, чтобы дать четкий ответ:

public void fun() {	
    int a = 1;
    float b = 2F;
    a += b;
}

// 反编译class的内容
public void fun() {
    byte var1 = 1;
    float var2 = 2.0F;        
    int var10000 = (int)((float)var1 + var2);
}

MDove: Так что разница между ними очень ясна, верно? В этом случае диапазон A меньше, чем у типа B.a = a + b;Требуется принуждение, о чем мы часто пишем:a = (int) (a+b);и нашa += b;Во время компиляции наш компилятор проделал небольшие хитрости. То есть компилятор помогает нам выполнить принудительное преобразование типов.

маленький А: Получается, что это так, какие проблемы принесет принудительное преобразование типов?

MDove: Чтобы ответить на этот вопрос, давайте сначала посмотрим на картинку:

MDove: Принудительное преобразование типа, что обычно приводит к проблеме потери точности. Диапазон float здесь слишком велик, мы будем использовать byte и short, чтобы продемонстрировать проблемы, вызванные принудительным типом:

public void fun() {
    byte a = 1;
    short b = 127;
    a=(byte) (a+b);
    System.out.println(a);
}

MDove: Контент, набранный Системой, вы должны знать, что это такое, верно? Правильно -128. Проблемы, вызванные принудительными типами, очевидны с первого взгляда.

маленький А: Как может быть -128?

MDove: Хорошо, теперь позвольте мне объяснить, почему -128 такое странное число. Во-первых, мы все знаемКоличество байтов, которое примитивный тип занимает в кучеСм. таблицу ниже.

маленький А: Разве это не правильно? Я помню, что основной типположить в стекАга?

MDove: Это утверждение хорошее, но неполное.Хранится ли она в куче или в стеке, зависит от того, где объявлена ​​переменная.. Если это локальная переменная, она будет сохранена во фрейме стека. Но если это переменная-член (глобальная переменная), она будет храниться в куче. Кроме того, байты, хранящиеся в стеке, фиксированы: если это 32-битный компьютер, то это 4 байта, 64-битный — 8 байт.

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

тип байты
byte 1 байт
short 2 байта
int 4 байта
long 8 байт
char 2 байта
float 4 байта
double 8 байт

MDove: После объяснения проблемы занятых байтов продолжим. Из вышеизложенного видно, что байт занимает 1 байт, то есть битов 8. Если каждый бит равен 1 (11111111), то теоретически это самое большое содержимое, которое он может представлять.

маленький А: Должно быть 255!

MDove: На самом деле нет, по положительным и отрицательным причинам компьютер использует форму дополнения для представления двоичного кода, а старший 1 бит представляет бит знака (0 — положительный, 1 — отрицательный). Следовательно, для 8 бит максимум может быть только 01111111, что равно 127. (0 означает, что это положительно)

MDove: И расчет, который мы только что сделалиbyte a = 1; short b = 127; a=(byte) (a+b);Независимо от преобразования типов, a+b правильно равно 128. А для короткого, занимающего 2 байта, т.е.00000000 10000000.但是我们强制类型转化成了byte,这时做了一件事情,那就是高1字节的内容全部砍掉,也就是只剩下了10000000.

MDove: Согласно тому, что мы только что сказали, содержимое старшего 1 бита указывает положительное или отрицательное значение. 1 отрицательный.

маленький А:! ! ! Если 1 отрицательно, то System.out должен быть равен 0..

MDove: Когда вы смотрите на свой двоичный файл, вы не учились усердно. Для формы дополнения до двух10000000, мы используем метод дополнения для расчета. Процедура вычисления следующая: старший 1 бит равен 1, тогда это отрицательное число. Чтобы узнать отрицательное число, нужно положить10000000Побитовая инверсия, т.е.01111111. Это еще не конец, в это время нам нужно добавить 1, что10000000. Число, полученное сейчас, равно нескольким, тогда это отрицательное число,10000000равно 128 в десятичном виде, поэтому в форме дополнения до двух10000000То есть: -128.

MDove: Объясняет ли это проблему, вызванную принудительным преобразованием типов, и почему байт после принудительного преобразования типов становится -128?

маленький А: Трудно учиться... Я хочу пойти домой и заняться фермой...

маленькая мама: Cub, не учи программирование, иди домой и собирай кукурузу.

конец пьесы

Вот публичный аккаунт, который ведет группа первокурсников.Содержимое - ямы, на которые мы наступили при переходе от первокурсников к разработке, а также запись нашего пошагового обучения.Если вам интересно, вы можете обратить внимание и подбодрить вместе Давайте работать вместе~! ~!

个人公众号:IT面试填坑小分队