Если нужен короткий ответ: литерал это значение, записанное прямо в коде, вот так, как оно есть: 42, 3.14, "Hello world!", 'A', true. Компилятор ничего не вычисляет, он берет написанное и кладет в программу. Литералы бывают целочисленные, с плавающей точкой, строковые, символьные, логические, плюс отдельно стоит null.

Кратко

  • Литерал это записанное в исходнике готовое значение. Переменная его хранит, литерал им является.
  • Целое число по умолчанию имеет тип int; чтобы получить long, в конце ставят L. Дробное по умолчанию double; чтобы получить float, ставят f.
  • Целые числа записывают в четырех системах счисления: двоичной (0b), восьмеричной (ведущий ноль), десятичной и шестнадцатеричной (0x). В переменную все равно попадает одно и то же число.
  • Строку заключают в двойные кавычки, символ в одинарные. Кавычку, слеш и служебные символы внутри строки экранируют обратным слешем.
  • Символ занимает 16 бит, поэтому эмодзи в char не помещается: его задают числом и разворачивают через Character.toChars().
  • Литералы уместны там, где значение не меняется. Параметры подключения к базе и прочие изменчивые вещи в исходник вписывать не стоит.
На этапе создания приложения разработчик, как правило, знает только его структуру и не предполагает, какие данные оно будет обрабатывать. Тем не менее, в некоторых ситуациях в коде программы нужно явно указывать какие-то данные (например, количество итераций или сообщение для вывода). В этом случае на помощь приходят литералы. Панель из множества красных семисегментных индикаторов с цифрамиСодержание:

Что такое литералы?

Литералы это явно заданные значения в коде программы, значения определенного типа, которые находятся в коде уже в момент запуска.

class Test {
   public static void main(String[] args) {
       System.out.println("Hello world!");
   }
}
В этом классе “Hello world!” это литерал. Литералы бывают разных типов, которые определяются их назначением и способом написания.

Типы литералов и их применение

Почти все литералы задают примитивные значения: числа, символы, логические. Отдельно стоят два: строковый литерал это уже готовый объект класса String, а null это пустая ссылка, которая подходит любому ссылочному типу. Литералов для собственных классов в Java нет: объект нельзя записать одним значением прямо в коде, его создают через конструктор. В соответствии с типами данных, литералы также делятся на разделы:
  1. Числовые:
    • Целочисленные;
    • С плавающей точкой;
  2. Строковые;
  3. Символьные;
  4. Логические.
Если шпаргалка нужна сразу, вот все виды литералов в одной таблице.
Вид литерала Как выглядит в коде Тип по умолчанию
Целочисленный 42, 0b1101, 017, 0x1F int, с суффиксом L это long
С плавающей точкой 3.14, 4.05E-13 double, с суффиксом f это float
Строковый "Hello world!" String
Текстовый блок (с Java 15) """несколько строк""" String
Символьный 'A', '\u00F7', '\122' char
Логический true, false boolean
Пустая ссылка null подходит любому ссылочному типу

Числовые литералы

Целочисленные литералы

Данный вид литералов самый простой. Числа записываются в их стандартном виде без указывающих символов и прочего. Любое целое число по умолчанию является целочисленным литералом. То есть можно явно задать значение переменной или количество итераций в цикле. В Java поддерживается 4 системы счисления:
  • Двоичная
  • Восьмеричная
  • Десятичная
  • Шестнадцатеричная
В JDK 7 появилась возможность записи двоичных значений. Делается это с помощью префикса 0b или 0B. Далее идет запись с использованием 0 и 1. Там же, в JDK 7, разрешили разделять цифры подчеркиванием: 1_000_000 и 0b1101_0101_10 компилятор читает как обычные числа, а человек как разряды. Ставить подчеркивание можно только между цифрами: не в начале и не в конце числа, не сразу после 0x или 0b и не перед суффиксом. Числа в восьмеричной системе записываются с помощью ведущего 0. Допустимые цифры: от 0 до 7. Запись 09 или 08 вызовет ошибку компиляции. С десятичной системой счисления нет никаких проблем: числа указываются в привычном нам виде. Единственное ограничение: число не может начинаться с 0, так как компилятор примет его за восьмеричное. Числа в шестнадцатеричной системе записываются с помощью префиксов 0x и 0X. Допустимые цифры: от 0 до 15, где числа 10-15 обозначаются символами A-F соответственно.

public static void main(String[] args) {
       int a = 0b1101010110;
       int b = 012314;
       int c = 456;
       int d = 0x141D12;
       System.out.println("Число a в двоичной системе: " + a);
       System.out.println("Число b в восьмеричной системе: " + b);
       System.out.println("Число c в десятичной системе: " + c);
       System.out.println("Число d в шестнадцатеричной системе: " + d);
}
Вывод: Число a в двоичной системе: 854 Число b в восьмеричной системе: 5324 Число c в десятичной системе: 456 Число d в шестнадцатеричной системе: 1318162 Несмотря на то, что числа задаются в разных системах счисления, в программе они обрабатываются как десятичные числа. Выход за пределы значений приведет к ошибке компиляции:

       int b = 012914; // Ошибка
       int d = 0x141Z12; // Ошибка
При запуске на этапе компиляции получим следующий результат:

Error:(13, 25) java: integer number too large: 012914
Error:(14,30) java: ';' expected

Тип целочисленного литерала: int и long

Любой целочисленный литерал по умолчанию имеет тип int. Если его значение выходит за пределы присваиваемой переменной, происходит ошибка компиляции. При использовании типа long необходимо в конце ставить символ L, обозначающий этот тип:

       long x = 0x1101010110; // Ошибка
       long b = 1342352352351351353L; // Все в порядке
Попытка компиляции приводит к такой ошибке:

Error(11, 26) java: integer number too large: 1101010110

Литералы с плавающей точкой

Числа с плавающей точкой, или дробные числа, могут записываться двумя способами. Первый, в качестве классической десятичной дроби: 3.14159 или 2.718281282459045. Второй, в научном виде: обычная десятичная дробь плюс суффикс в виде латинской буквы e или E и степени 10, на которую нужно умножить указанную дробь. Например, 4.05E-13, это значит 4.05 * 10-13.

       double a = 2.718281828459045;
       double d = 4.05E-13;
       System.out.println("Тип double в классическом виде: " + a);
       System.out.println("Тип double в научном виде: " + d);
Вывод: Тип double в классическом виде: 2.718281828459045 Тип double в научном виде: 4.05E-13 В отличие от целых чисел и систем счисления, научная форма записи сохраняется в переменной и обрабатывается так же, как классическая форма.

Тип дробного литерала: double и float

Любое число с плавающей точкой по умолчанию имеет тип double. При желании это можно подчеркнуть суффиксом d или D: 2.5d. Если нужен float, в конце ставят f или F, и тогда литерал сразу имеет тип float, никакого преобразования из double не происходит. Автоматически double в float не сужается, поэтому без суффикса будет ошибка:

       float a = 2.718281828459045; // Ошибка
       float d = 4.05E-13F; // Все в порядке
При запуске на этапе компиляции видим такую ошибку:

Error:(11, 27) java: incompatible types: possible lossy conversion from double to float

Строковые литералы

Строковые литералы это набор символов, заключенных в двойные кавычки. Данный тип используется так же часто, как и числовые литералы, а работать с такой строкой дальше вы будете через класс String. В строке также могут находиться служебные символы, которые необходимо экранировать (так называемые escape-последовательности). Пример:

       String simpleString = "Это обычная строка. Такая же стандартная и непримечательная, как и все мы.";
       String uniqueString = "А это необычная \"строка\". Хотя бы потому, что часть \"слов\" в ней в \"кавычках\".";
       System.out.println(simpleString);
       System.out.println(uniqueString);
Вывод: Это обычная строка. Такая же стандартная и непримечательная, как и все мы. А это необычная "строка". Хотя бы потому, что часть "слов" в ней в "кавычках".

Текстовые блоки: строка на несколько строк

С Java 15 у строкового литерала появилась вторая форма записи: текстовый блок в тройных кавычках. Переносы строк внутри него пишутся как есть, без \n, а двойные кавычки не нужно экранировать. Общий отступ слева компилятор срезает сам, поэтому блок можно держать вровень с остальным кодом.

       String text = """
               Первая строка.
               Вторая строка.
               И "кавычки" внутри писать можно как есть.""";
       System.out.println(text);
Вывод: Первая строка. Вторая строка. И "кавычки" внутри писать можно как есть.

Символьные литералы

Символьные литералы в Java представлены кодовой таблицей Unicode, то есть каждый символ это 16-битовое значение. Для обозначения символа в коде его обособляют одинарными кавычками. По опыту использования бывают два вида символов:
  1. Те, что можно ввести с клавиатуры, это обычные символы;
  2. Символы, которые просто так с клавиатуры не ввести (символы различных языков, фигуры и так далее).
Обычные символы можно указать в явном виде: ‘,’ или ‘@’. Если символ служебный (например, перенос строки или табуляция), такой символ необходимо экранировать обратным слешем. Вот все такие последовательности.
Запись Что означает
\n перевод строки
\t горизонтальная табуляция
\r возврат каретки
\b забой, backspace
\f перевод страницы, form feed
\s пробел, добавлена в Java 15
\" двойная кавычка
\' одинарная кавычка
\\ сам обратный слеш
\0 ... \377 символ по восьмеричному коду, максимум 255
\u0000 ... \uFFFF символ по шестнадцатеричному коду Unicode; обрабатывается еще до компиляции, поэтому работает в любом месте кода, а не только внутри кавычек
Символы, которые нельзя просто так ввести с консоли, можно задать в их 16-битовом виде. Для этого необходимо указать код символа с префиксом \u, например ‘\u00F7’. Также символы можно указывать в восьмеричном стиле (от одной до трех восьмеричных цифр, максимум \377), добавив в начале просто обратный слеш, например ‘\122’. На мой взгляд, гораздо легче использовать \u. Пример использования:

       System.out.println("Амперсанд - " + '&');
       System.out.println("Символ деления - " + '\u00F7');
Вывод: Амперсанд - & Символ деления - ÷

Логические литералы

Самый простой литерал это логический. Имеется всего 2 значения: false и true, которые указываются явно без различных символов. Такие литералы могут быть присвоены переменным типа boolean или указаны в месте, где ожидается тип boolean (например, в блоке if, хотя такая практика считается, мягко говоря, моветоном).

       boolean flag = false;

       if(true) {
           // Действия будут выполняться всегда.
       }

Джедайская техника с литералами

Благодаря символам в Java можно делать много интересных штук, в числе которых управление эмоджи. Например, выведем улыбающееся лицо:

       int smile = 0x1F600; // Здесь шестнадцатеричный код эмоджи
       StringBuilder sb = new StringBuilder();
       sb.append(Character.toChars(smile)); // Собираем в StringBuilder
       System.out.println("Улыбающееся лицо: " + sb.toString()); // Выводим
Вывод: Улыбающееся лицо: 😀 Несмотря на то, что отображение эмоджи может быть жутковатым (в зависимости от реализации), это решение неплохо справляется с задачей. Однако в стандартной таблице кодировок сложно искать нужные эмоджи, на официальном сайте раздел Эмотикон скуден. Гораздо проще воспользоваться дополнительными библиотеками.

Литералы в курсе JavaRush

В курсе JavaRush литералы изучаются на 10 уровне в 8 лекции курса Java Syntax, где на примерах объясняется, что такое литералы и зачем они нужны. JavaRush это онлайн-курсы по программированию с акцентом на практику: 3000+ задач с моментальной проверкой, мини-проекты, игры. Начать обучение на JavaRush

Заключение

Литералы в Java удобная вещь в любой программе, однако использовать их необходимо в тех местах, где это уместно. Не стоит хардкодить в исходниках параметры подключения к БД или какие-либо значения, которые могут измениться во время жизненного цикла программы.

Вопросы и ответы

Чем литерал отличается от переменной?

Переменная это именованная ячейка, в которой значение лежит и может меняться. Литерал это само значение, написанное в коде буквами и цифрами. В строке int count = 42; count переменная, а 42 литерал. Литералу нельзя ничего присвоить и на него нельзя сослаться по имени.

Какой тип у числа, записанного прямо в коде?

Целое число по умолчанию int, даже если вы присваиваете его переменной long. Чтобы литерал стал long, в конце нужна буква L: 1342352352351351353L. Дробное число по умолчанию double; чтобы получить float, в конце ставят f или F.

Почему int x = 08; не компилируется?

Потому что ведущий ноль означает восьмеричную систему, а в ней есть только цифры от 0 до 7. Восьмерка и девятка в такой записи недопустимы. Если нужно обычное десятичное число, ноль в начале просто не пишут: int x = 8;.

Как сделать длинное число в коде читаемым?

С JDK 7 цифры можно разделять подчеркиванием: 1_000_000 читается глазом куда лучше, чем 1000000, а для компилятора это одно и то же число. Работает во всех системах счисления: 0b1101_0101_10, 0x141D_12. Подчеркивание ставят только между цифрами, не в начале и не в конце числа, не сразу после 0x или 0b и не перед суффиксом.

Почему эмодзи не помещается в переменную типа char?

char это 16 бит, то есть коды от 0 до 65535. Улыбающееся лицо имеет код 0x1F600, а это 128512, и в 16 бит оно не влезает. Поэтому код держат в int, а Character.toChars() раскладывает его на два char, суррогатную пару, которую уже можно добавить в строку.

Как записать в коде текст на несколько строк?

С Java 15 для этого есть текстовый блок: текст помещают между тройными кавычками """. Переносы строк сохраняются как есть, \n не нужен, двойные кавычки внутри не надо экранировать, а общий отступ слева компилятор срезает. До Java 15 приходилось склеивать строки плюсом и вставлять \n вручную.

Что такое литерал null?

Это единственный литерал, который не относится ни к одному конкретному типу: у него собственный null-тип, и он подходит любой ссылочной переменной, будь то String, массив или ваш класс. Присвоить null примитиву нельзя: int x = null; не скомпилируется. Источник: Oracle, Java Language Specification, раздел 3.10 Literals.

Читайте также