предисловие
Скорочтение коротких текстов, это будет цикл статей. Я сам написал и прочитал много статей. Я обнаружил, что многие из них представляют собой сборники, а не сериалы. Конечно, когда у меня будет время, я действительно найду сборники статей и хорошо их изучу. Но большинство статей словно тонет в море и теряет свою ценность.
Поэтому родилась идея этой серии.Характеристики серии статей: взять за основу какие-то базовые знания в ежедневной разработке, и обернуть вокруг этого понятный текст. Попробуйте рассказать часть знаний в режиме меньшего размышления. Давайте на самом деле узнаем что-то в разрозненное время!
Эйнштейн: «Если вы не можете что-то просто объяснить, вы на самом деле этого не понимаете».
[Скорочтение короткого текста-1] Разница между a=a+b и a+=b
[Короткая скорость текста-4] Будет ли новый подкласс создавать экземпляр родительского класса?
Внешний вид роль
маленький А: Только начинаю программировать на 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, не учи программирование, иди домой и собирай кукурузу.