W3docs

Операторы присваивания в Java

Присваивайте значения переменным с помощью =, +=, -=, *=, /=, %= и составных побитовых операторов присваивания.

Одиночный = — это базовый оператор присваивания. Java также предоставляет семейство составных операторов присваивания, которые объединяют арифметическую, побитовую операцию или операцию сдвига с самим присваиванием. Они сокращают код и делают намерение — «изменить эту переменную на месте» — более понятным.

Простое присваивание

Правая часть вычисляется, а затем сохраняется в переменную в левой части:

int x = 5;
int y = x + 3;
y = y * 2;
System.out.println(y);   // 16

Несколько правил:

  • Левая часть должна быть переменной (или элементом массива, или полем), но не выражением вроде (x + 1) = 5.
  • Типы должны совпадать — или правая часть должна быть неявно приводима к типу левой части.
  • Присваивание само по себе является выражением: int a = (b = 5); устанавливает и a, и b в значение 5.

Составные операторы присваивания

Каждый арифметический и побитовый оператор имеет парный составной оператор присваивания:

ОператорПолная форма
+=x = x + value
-=x = x - value
*=x = x * value
/=x = x / value
%=x = x % value
&=x = x & value
`=`
^=x = x ^ value
<<=x = x << value
>>=x = x >> value
>>>=x = x >>> value

На практике:

int total = 0;
total += 5;    // total = 5
total += 3;    // total = 8
total *= 2;    // total = 16
total -= 1;    // total = 15
total /= 3;    // total = 5

Побитовые операторы и операторы сдвига работают так же — они применяют операцию к текущему значению переменной и сохраняют результат обратно:

int flags = 0b0101;   // 5
flags |= 0b0010;      // set a bit  -> 0b0111 = 7
flags &= 0b0110;      // clear bits -> 0b0110 = 6
flags <<= 1;          // shift left -> 0b1100 = 12

Правая часть группируется целиком

x op= y — это не слепая текстовая подстановка x = x op y. Компилятор рассматривает всю правую часть как один операнд, как если бы она была в скобках — x = x op (y):

int x = 10;
x *= 2 + 3;   // x = x * (2 + 3) = 50, NOT x = x * 2 + 3 = 23
System.out.println(x);   // 50

+= со строками

+= также выполняет конкатенацию строк:

String greeting = "Hello";
greeting += ", world!";   // "Hello, world!"

Каждый += для String создаёт новую строку под капотом — строки неизменяемы. Для циклов, которые формируют длинную строку, используйте StringBuilder (рассматривается в Java String Concatenation).

Составное присваивание включает неявное приведение типов

Тонкая, но важная особенность: составные операторы присваивания включают неявное приведение обратно к типу переменной. Простое присваивание этого не делает.

byte b = 10;
// b = b + 1;       // compile error: int can't fit into byte without a cast
b += 1;             // OK — compound form casts implicitly
System.out.println(b);   // 11

Это иногда полезно — и иногда является скрытой ловушкой, если прячет переполнение.

Присваивание является выражением — но не злоупотребляйте этим

Поскольку присваивание возвращает значение, его можно выстраивать в цепочку:

int a, b, c;
a = b = c = 10;     // all three set to 10

Можно также выполнять присваивание внутри условия if:

String line;
while ((line = reader.readLine()) != null) {
    process(line);
}

Эти идиомы распространены в циклах ввода-вывода. За пределами конструкции while ((x = ...) != null) предпочитайте отдельные операторы — их легче читать.

= против ==

Самый распространённый источник ошибок, возникающих из-за одного символа в Java, — путаница между = (присваивание) и == (сравнение):

int x = 5;
// if (x = 10) { ... }   // compile error: int is not a boolean
// if (x == 10) { ... }  // OK

Для int и большинства типов компилятор немедленно обнаруживает ошибку, потому что = возвращает int, а не boolean. С переменными типа boolean ошибки компиляции нет — присваивание с = всегда возвращает присвоенное boolean-значение — поэтому будьте особенно осторожны при проверке флагов:

boolean isOpen = false;
if (isOpen = true) { ... }   // bug: this sets isOpen and is always true
if (isOpen == true) { ... }  // works, but...
if (isOpen) { ... }          // ...this is what you actually want

Демонстрация

java— editable, runs on the server

Что дальше

Java Comparison Operators охватывает ==, !=, операторы отношения и принципиальное различие между == и .equals() для объектов.

Практика

Практика
Что выведет этот код?\n\nint x = 10;\nx += 5;\nx *= 2;\nSystem.out.println(x);
Что выведет этот код?\n\nint x = 10;\nx += 5;\nx *= 2;\nSystem.out.println(x);
Was this page helpful?