Перейти к содержимому
Теория · Операторы и выражения · урок 7 из 8

Строки и числа: + и format

У калькулятора Java есть ещё одно правило, и касается оно оператора +. Пока с обеих сторон от него числа, он складывает. Как только с одной из сторон оказывается текст, + перестаёт считать и начинает склеивать.

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

JAVA
public class Main {
    public static void main(String[] args) {
        System.out.println(1 + 2 + "3"); // 33
        System.out.println("1" + 2 + 3); // 123
    }
}

Java выполняет + слева направо, по одному:

  1. В первом println сначала идёт 1 + 2. Оба значения — числа, поэтому получается 3. Затем 3 + "3": справа текст, и + склеивает, выходит 33.
  2. Во втором println первым стоит текст. "1" + 2 даёт 12, а "12" + 3 даёт 123. До сложения чисел дело не доходит.

Аналогия с экраном неточна в одном: на экране 3 и "3" выглядят одинаково, а для Java это разные значения. Число 3 можно складывать, а строка "3" — это текст, и складывать её Java не будет.

Склейка строк

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

JAVA
String name = "Anna";
System.out.println("Hi, " + name);   // Hi, Anna
System.out.println("Price: " + 2.5); // Price: 2.5
System.out.println("1" + (2 + 3));   // 15

Давайте разберём по порядку:

  1. name — переменная типа String, она хранит текст Anna. "Hi, " + name склеивает две строки.
  2. "Price: " + 2.5 превращает число 2.5 в текст и приписывает его к строке.
  3. В "1" + (2 + 3) скобки выполняются первыми: 2 + 3 даёт 5, и только потом "1" + 5 склеивает 15.

Этот вопрос любят задавать на собеседовании: что напечатает 1 + 2 + "3", а что "1" + 2 + 3? Оба ответа следуют из одного правила: + выполняется слева направо, и после первой строки он только склеивает.

Печать по шаблону

Длинную строку из кусков и плюсов трудно читать. Удобнее String.format: он заполняет шаблон, как бланк с пропусками. На месте пропусков в шаблоне стоят метки с %, а значения для них идут следом, по порядку:

  • %d — целое число;
  • %.2f — дробное число, округлённое до двух знаков после запятой;
  • %s — строка или любое значение как текст;
  • %n — перевод строки.
JAVA
String name = "Anna";
int age = 30;
double height = 1.6789;
String line = String.format("%s is %d, %.2f m", name, age, height);
System.out.println(line);                   // Anna is 30, 1.68 m
System.out.printf("%s is %d%n", name, age); // Anna is 30

Разберём, что здесь происходит:

  1. String.format берёт шаблон и три значения. Метка %s заменяется на Anna, %d на 30, а %.2f на 1.68: число округлилось до двух знаков.
  2. Результат — обычная строка. Её кладут в line и печатают.
  3. System.out.printf делает то же самое, но сразу печатает результат. Как и print, он не переводит строку сам, поэтому шаблон заканчивается на %n.

Разделитель дробной части %.2f берёт из языковых настроек компьютера. С английскими настройками программа печатает 1.68, как в комментарии, а с русскими — 1,68. А + и println печатают дробь всегда с точкой.

Метка должна подходить к значению. Если передать 2.5 в метку %d, программа остановится с исключением IllegalFormatConversionException.

Частая ошибка

Сумму двух чисел приписывают к строке без скобок:

JAVA
public class Main {
    public static void main(String[] args) {
        int apples = 2;
        int pears = 3;
        String text = "Fruit: " + apples + pears; // ✗
        System.out.println(text);                  // Fruit: 23
    }
}

Хотели напечатать Fruit: 5, а получили Fruit: 23. Первый + склеил строку с 2, и слева от второго + уже стоит строка. Поэтому 3 приклеилась к тексту, а не прибавилась к 2. Возьмите сумму в скобки: "Fruit: " + (apples + pears) печатает Fruit: 5.

Главное

  • Если с одной стороны от + стоит строка, он склеивает, а не складывает.
  • + выполняется слева направо: 1 + 2 + "3" — это 33, а "1" + 2 + 3 — это 123.
  • Чтобы сложить числа внутри строки, возьмите сумму в скобки: "1" + (2 + 3) — это 15.
  • String.format и printf подставляют значения в шаблон по меткам %d, %.2f и %s, а %n переводит строку.