что такое строковый литерал java
Литералы
Целочисленные литералы
Восьмиричные значения обозначаются ведущим нулем (обычные десятичные числа не могут иметь ведущий нуль). По этой причине с виду нормальное число 09 вызовет ошибку компиляции, так как выйдет за пределы диапазона от 0 до 7 допустимых восьмеричных значений.
Целочисленные литералы создают значения типа int. Если вы создали переменную типа byte или long, а значение литерала находится в диапазоне допустимых значений этих типов, то ошибки не возникает. Не возникает проблем и с типом long, у которого диапазон значений всегда больше, чем у int. Но при этом нужно явно указать, что значение литерала имеет тип long при помощи строчной или прописной буквы L. Например, 899888777666555444333L.
Целочисленное значение можно также присвоить типу char, если оно лежит в допустимых пределах.
Литералы с плавающей точкой
По умолчанию литералам с плавающей точкой присвоен тип double. Если вам нужен тип float, то нужно дописать символ F или f. Кстати, для double можно использовать суффиксы D или d, но в этом нет необходимости.
Символьные литералы
В Java символы представляют собой 16-битовые значения в наборе символов Unicode. Эти значения можно преобразовать в целые значения и применить операции сложения и вычитания. Символьные литералы обрамляются одинарными кавычками. Обычные символы можно ввести стандартным способом, например, ‘c’, ‘a’, ‘@’. Существуют также символы, которые следует экранировать обратным слешем, например, чтобы вывести сам символ одинарной кавычки, нужно использовать вариант ‘\n». Для символа новой строки используется ‘\n’.
Для ввода шестнадцатиричного значения используют обратный слеш, символ u, за которыми следуют четыре шестнадцатиричные цифры, например, ‘\u0061’.
Строковые литералы
Булевы литералы
JDK 7
Раньше Android не поддерживал JDK 7. Сейчас поддержка имеется и стали доступны новые возможности.
В JDK 7 можно использовать целочисленные литералы в двоичной системе. Для этого нужно использовать префикс 0b или 0B:
Кроме того, в JDK 7 можно вставлять символы подчёркивания для облегчения чтения больших числовых литералов:
Символы подчёркивания будут проигнорированы компилятором. Учтите, что можно использовать несколько подряд символов подчёркивания, но нельзя использовать символы подчёркивания в начале или в конце литерала.
Подобная запись удобна при записи вручную программистом номеров телефонов и тому подобных вещей, чтобы визуально лучше анализировать значения. А умная железка сама разберётся, что к чему и не будет удивляться символам подчёркивания в числах.
Литералы
Значения примитивных типов данных в большинстве случаев инициализируются с помощью литералов. Давайте рассмотрим какого типа они бывают в Java.
1. Числовые литералы
1.1. Целочисленные литералы
Типы целочисленных литералов в Java:
Десятичные литералы
Восьмеричные литералы
Восьмеричные литералы начинаются с 0 и используют числа от 0 до 7, например:
Шестнадцатеричные литералы
Двоичные литералы в Java 7
Для определения двоичного литерала, добавьте префикс 0b или 0B к числу. Используются числа 0 и 1. Например:
1.2. Литералы с плавающей точкой
Можно добавить символ ‘D’ или ‘d’ к double литералу, но это не обязательно:
Существует так называемая научная нотация записи вещественных чисел:
Значение этого числа равно 1.5 умножить на 10 в четырнадцатой степени.
1.3. Подчеркивание в числовых литералах
Начиная с Java 7, добавлена возможность использовать любое количество символов подчеркивания для разделения групп цифр, что улучшает читабельность.
Подчеркивание может разделять только цифры! Нельзя использовать подчеркивания в следующих местах:
2. Boolean литералы
Значение литерала типа boolean может быть определено как true или false :
3. Символьные литералы
Для представления символов типа char в Java используется кодировка в Unicode, определяющая полный набор международных символов на всех известных языках мира.
Символьные литералы могут быть представлены в виде символа заключенного в одинарные кавычки:
Существует также механизм для непосредственного ввода значения символа в восьмеричной или шестнадцатеричной форме. Для ввода значений в восьмеричной форме служит символ обратной косой черты, за которым следует трехзначное число. Например:
Есть возможность присвоения числового литерала символьному типу. Числовой литерал должен находиться в диапазоне от 0 до 65535. Например:
Символ обратной косой черты может быть использован для обозначения символов не имеющих точного написания, например символ перевода строки, табуляции, backspace, двойные и одинарные кавычки:
Литералы
— И, наконец, урок от Риши в лекторском стиле: куча бесполезной информации. Все лекторы обожают такое. Но ты хотя бы одним глазком посмотри, и хватит с тебя.
Код | Описание |
---|---|
«Mama mila ramu» | Это литерал. Его тип — String |
115 | Это литерал. Его тип — int |
0.256 | Это литерал. Его тип – double |
‘\u1234’ | Это литерал. Его тип – char |
— На самом деле литералов несколько больше. С помощью литералов можно задать значения любых известных типов:
Литерал | Тип | Описание |
---|---|---|
123676 | int | Целое число |
22223333444433332222L | long | Длинное целое число |
12.323232323f | float | Дробное число |
12.33333333333333333d | double | Длинное дробное число |
«Mama» «» «Mama\nMila\nRamu\n123» | String | Строка |
‘\u3232’ ‘T’ ‘5’ | char | Символ |
true, false | boolean | Логический тип |
null | Object | Ссылка на объект |
— Т.е. код – это методы, классы, переменные,…, а литералы – это конкретные значения переменных, записанные прямо в коде. Так, я правильно понял?
— Отлично. Наконец-то эта Java начинает складываться в одну картину.
Работа со строками Java
Тип данных может содержать последовательность (строку) символов. После создания строки вы можете искать внутри нее, создавать из нее подстроки, новые строки на основе первой, но с заменой некоторых частей, а также многое другое.
Представление
Строка Java (до Java 9) представлена внутри Java VM с использованием байтов, закодированных как UTF-16. UTF-16 использует 2 байта для представления одного символа. Таким образом, символы строки представляются с использованием массива char.
UTF – это кодировка символов, которая может представлять символы из разных языков (алфавитов). Вот почему необходимо использовать 2 байта на символ – чтобы иметь возможность представлять все эти разные символы в одной строке.
Компактные строки
Начиная с Java 9 и выше, Java VM может оптимизировать строки с помощью новой функции, называемой компактными строками. Она позволяет виртуальной машине определять, содержит ли строка только символы ISO-8859-1 / Latin-1. Если это так, она будет использовать только 1 байт на символ внутри. Таким образом, символы компактной строки могут быть представлены байтовым массивом вместо массива char.
Может ли String быть представлена в виде компактной строки или нет, определяется при создании строки. Однажды созданная строка является неизменной, поэтому это безопасно.
Создание строки
Строки являются объектами. Поэтому нужно использовать оператор new для создания нового объекта Java String:
Текст внутри кавычек – это текст, который будет содержать объект String.
Строковые литералы
Есть более короткий способ создания новой строки:
Вместо того, чтобы передавать текст «Hello World» в качестве параметра конструктору String, вы можете просто написать сам текст внутри символов двойной кавычки. Это называется строковым литералом. При компиляции Java кода самостоятельно определяется, как будет создана новая строка, представляющая данный текст.
Escape-символы
Литералы Java Strings принимают набор из которых переводятся в специальные символы в созданной строке. Пример создания с использованием escape-символов:
Этот строковый литерал приведет к строке, которая начинается с символа табуляции и заканчивается переводом каретки и символом новой строки.
Константы
Если вы используете ту же строку (например, «Hello World») в других объявлениях переменных String, виртуальная машина Java может создать в памяти только один экземпляр String. Таким образом, строковый литерал становится де-факто константой или синглтоном. Различные переменные, инициализированные одной и той же константной строкой, будут указывать на один и тот же экземпляр String в памяти.
В этом случае виртуальная машина заставит myString1 и myString2 указывать на один и тот же объект String.
Точнее говоря, объекты, представляющие литералы Java String, получены из пула констант String, который виртуальная машина Java хранит внутри. Это означает, что даже классы из разных проектов, скомпилированные отдельно, но используемые в одном приложении, могут совместно использовать объекты String. Обмен происходит во время выполнения. Это не функция времени компиляции.
Если вы хотите быть уверены, что две строковые переменные указывают на отдельные строковые объекты, используйте оператор new следующим образом:
Даже если значение (текст) двух созданных строк Java одинаково, виртуальная машина Java создаст в памяти два разных объекта для их представления.
Конкатенация строк
Конкатенация строк означает добавление одной строки к другой. Строки являются неизменными, то есть они не могут быть изменены после создания. Поэтому при объединении двух объектов Java String друг с другом результат фактически помещается в третий объект String.
Содержимое строки, на которую ссылается переменная три, будет Hello World. Два других объекта Strings нетронуты.
Производительность конкатенации
При объединении строк вам следует остерегаться возможных проблем с производительностью. Конкатенация двух строк будет преобразована компилятором Java в нечто вроде этого:
Создается новый StringBuilder, который передает первую строку в свой конструктор, а вторую – в свой метод append(), прежде чем вызвать метод toString(). Этот код фактически создает два объекта: экземпляр StringBuilder и новый экземпляр String, возвращенный методом toString().
При выполнении самих себя в виде одного оператора эти дополнительные затраты на создание объекта незначительны. Однако когда выполняется внутри цикла, это другая история.
Вот цикл, содержащий вышеуказанный тип конкатенации строк:
Этот код будет скомпилирован в нечто похожее на это:
Теперь для каждой итерации в этом цикле создается новый StringBuilder. Кроме того, объект String создается методом toString(). Это приводит к небольшим расходам на создание экземпляров за одну итерацию: один объект StringBuilder и один объект String. Само по себе не является настоящим убийцей производительности, хотя.
Каждый раз, когда выполняется новый код StringBuilder(result), конструктор StringBuilder копирует все символы из результирующего String в StringBuilder. Чем больше итераций цикла, тем больше будет результат String. Чем больше растет результат String, тем больше времени требуется для копирования символов из него в новый StringBuilder и повторного копирования символов из StringBuilder во временную строку, созданную методом toString(). Другими словами, чем больше итераций, тем медленнее становится каждая итерация.
Самый быстрый способ объединения строк – создать StringBuilder один раз и повторно использовать один и тот же экземпляр внутри цикла. Вот как это выглядит:
Этот код избегает как экземпляров объектов StringBuilder и String внутри цикла, так и, следовательно, позволяет избежать двухкратного копирования символов, сначала в StringBuilder, а затем снова в String.
Длина строки
Длина строки – это количество символов, которое содержит строка, а не количество байтов, используемых для представления строки. Получить ее можно, используя метод length():
Подстроки
Вы можете извлечь часть строки – подстроку с помощью метода substring() класса String:
После выполнения этого кода переменная substring будет содержать строку Hello.
Первый символ в строке имеет индекс 0, второй символ имеет индекс 1 и т. д. Последний символ в строке имеет индекс String.length() – 1.
Поиск с помощью indexOf()
Вы можете искать подстроки в Strings, используя метод indexOf():
Существует версия метода indexOf(), которая берет индекс, с которого начинается поиск. Таким образом, вы можете искать в строке, чтобы найти более одного вхождения подстроки:
Этот код просматривает строку «это хорошо или это плохо?» для вхождений подстроки “is”. Для этого используется метод indexOf(substring, index). Параметр index указывает, с какого индекса символа в строке следует начать поиск. В этом примере поиск начинается с 1 символа после индекса, в котором было найдено предыдущее вхождение.
Подстрока “is” находится в четырех местах. Два раза в словах «есть» и два раза внутри слова «этот».
Класс Java String также имеет метод lastIndexOf(), который находит последнее вхождение подстроки:
Выход – 21, который является индексом последнего вхождения подстроки “is”.
Сопоставление строки с регулярным выражением с помощью match()
Метод Java String match() принимает регулярное выражение в качестве параметра и возвращает true, если регулярное выражение соответствует строке, и false, если нет:
Сравнение
Строки также имеют набор методов, используемых для сравнения строк:
equals()
Метод equals() проверяет, точно ли две строки равны друг другу. Если они есть, возвращается true. Если нет, false:
Две строки одна и три равны, но одна не равна двум или четырем. Регистр символов также должен совпадать, поэтому строчные буквы не равны прописным.
Вывод, напечатанный из кода выше, будет:
equalsIgnoreCase()
Класс String также имеет метод equalsIgnoreCase(), который сравнивает две строки, но игнорирует регистр символов. Таким образом, заглавные буквы считаются равными их строчным эквивалентам.
StartWith() и EndWith()
Методы StartWith() и EndWith() проверяют, начинается ли String с определенной подстроки:
В этом примере создается строка и проверяется, начинается ли она и заканчивается ли она различными подстроками.
compareTo()
Метод compareTo() сравнивает строку с другой и возвращает int, сообщающий, меньше ли эта строка, равна или больше другой.
В этом примере сравнивается одна строка с двумя другими. Вывод:
Числа отрицательны, потому что одна строка находится в порядке сортировки раньше, чем две другие.
Метод compareTo() фактически принадлежит интерфейсу Comparable.
Вы должны знать, что метод compareTo() может работать некорректно для строк на языках, отличных от английского. Чтобы правильно отсортировать строки на определенном языке, используйте Collator.
Обрезка посредством trim()
Класс Java String содержит метод trim(), который может обрезать строковый объект. Предназначен для удаления в начале и конце строки пробелов, табуляцию и переход на новую строку:
После выполнения этого кода усеченная переменная будет указывать на экземпляр String со значением
Пробельные символы в начале и конце объекта String были удалены. Символ пробела внутри строки не был затронут. Имеется в виду между первым и последним символом, не являющимся пробелом.
Метод trim() не изменяет экземпляр String. Вместо этого он возвращает новый объект Java String, который равен объекту String, из которого он был создан, но с удаленным пробелом в начале и конце строки.
Метод trim() может быть очень полезен для обрезки текста, введенного пользователем в поля ввода. Например, пользователь может ввести свое имя и случайно поставить дополнительный пробел после последнего слова или перед первым словом. Метод trim() – это простой способ удалить такие лишние пробелы.
Замена символов replace()
Класс Java String содержит метод replace(), который может заменять символы в строке. Он фактически не заменяет символы в существующей строке. Скорее, возвращает новый экземпляр String. Он равен экземпляру String, из которого он был создан, но с заменой указанных символов. Пример:
После выполнения этого кода замененная переменная будет указывать на строку с текстом:
Метод replace() заменит все символы, соответствующие символу, переданному методу в качестве первого параметра, вторым символом, переданным в качестве параметра.
replaceFirst()
Метод Java String replaceFirst() возвращает новую строку с первым совпадением регулярного выражения, переданного в качестве первого параметра, со строковым значением второго параметра:
Возвращается строка «один пять три два один».
replaceAll()
Метод Java String replaceAll() возвращает новую строку со всеми совпадениями регулярного выражения, переданного в качестве первого параметра, со строковым значением второго параметра:
Возвращается строка «один пять три пять один».
Разделение
Класс Java String содержит метод split(), который можно использовать для разделения String на массив объектов String:
После выполнения этого кода Java массив вхождений будет содержать экземпляры String:
Исходная строка была разделена на символы a. Возвращенные строки не содержат символов a. Символы a считаются разделителями для деления строки, а разделители не возвращаются в результирующий массив строк.
Параметр, передаваемый методу split(), на самом деле является регулярным выражением Java, которые могут быть довольно сложными. Приведенное выше соответствует всем символам, даже буквам нижнего регистра.
Метод String split() существует в версии, которая принимает ограничение в качестве второго параметра – limit:
Параметр limit устанавливает максимальное количество элементов, которое может быть в возвращаемом массиве. Если в строке больше совпадений с регулярным выражением, чем заданный лимит, то массив будет содержать совпадения с лимитом – 1, а последним элементом будет остаток строки из последнего среза – 1 совпадением. Итак, в приведенном выше примере возвращаемый массив будет содержать эти две строки:
Первая строка соответствует регулярному выражению. Вторая – это остальная часть строки после первого куска.
Выполнение примера с ограничением 3 вместо 2 приведет к тому, что эти строки будут возвращены в результирующий массив String:
Обратите внимание, что последняя строка по-прежнему содержит символ в середине. Это потому, что эта строка представляет остаток строки после последнего совпадения (a после ‘n водил с’).
Выполнение приведенного выше примера с пределом 4 или выше приведет к тому, что будут возвращены только строки Split, поскольку в String есть только 4 совпадения с регулярным выражением a.
Преобразование чисел в строку с помощью valueOf()
Класс содержит набор перегруженных статических методов с именем valueOf(), которые можно использовать для преобразования числа в строку:
Преобразование объектов в строки
Класс Object содержит метод с именем toString(). Поскольку все классы Java расширяют (наследуют) класс Object, все объекты имеют метод toString(). Он может использоваться для создания строкового представления данного объекта:
Примечание. Чтобы метод toString() возвращал нормальное String представление заданного объекта, класс объекта должен переопределить метод toString(). Если нет, то будет вызван метод toString() по умолчанию (унаследованный от класса Object), которые не предоставляет столько полезной информации.
Получение символов и байтов
Можно получить символ по определенному индексу в строке, используя метод charAt():
Этот код распечатает:
Так как это символы, расположенные в индексах 0 и 3 в строке.
Вы также можете получить байтовое представление метода String, используя метод getBytes():
Первый вызов getBytes() возвращает байтовое представление строки, используя кодировку набора символов по умолчанию на машине. Набор символов по умолчанию зависит от компьютера, на котором выполняется код. Поэтому обычно лучше явно указать набор символов, который будет использоваться для создания представления байтов (как в следующей строке).
Второй вызов getBytes() возвращает UTF-8-байтовое представление String.
Преобразование в верхний и нижний регистр
Вы можете конвертировать строки в верхний и нижний регистр, используя методы toUpperCase() и toLowerCase():
Java Core для самых маленьких. Часть 3. Переменные
В предыдущей статье мы говорили о типах данных, а теперь поговорим о вытекающей из этого теме, о переменных.
На скриншоте выше продемонстрирован пример создания переменных.
Давайте сразу научимся давать имена переменным правильно. Существует документ Java Code Conventions. В нем указаны правила к написанию кода на Java. Нужно это для того, что бы Java код в разных проектах был написан в едином стиле. Таким образом, новоприбывший на проект программист не будет отвлекаться на новый стиль кода, ведь он будет оформлен так же, как и на других проектах. Эти правила работают и при нейминге переменных.
Итак, переменные принято называть в lowerCamelCase стиле. Сейчас покажу как хорошо, а как плохо:
Вот было значение 1998, а на следующей строке стало 2000. А вот с константой так не получится. Константа гарантирует, что ее значение не изменится на протяжении всего времени выполнения программы. Как создать константу? Очень просто:
Нужно всего лишь дописать ключевое слово final перед типом данных переменной. Для простоты понимания, мы как бы «финализируем» значение переменной и говорим, что это значение конечное.
Обратим внимание на имя константы. Когда мы даем имя константе, то должны делать это в стиле SCREAMING_SNAKE_CASE. Давайте исправим мой код:
В целом, вас никогда не погладят по головке за правильный нейминг в коде. Подразумевается, что это нечто естественное при написании кода. Как правила этикета у людей. А вот если вы будете называть ваши переменные и константы абы как, получите незамедлительного леща.
Инициализация переменных
У всех переменных из моих примеров уже было присвоено начальное значение. Процесс присвоения начального значения называется инициализацией переменной. И не обязательно инициализировать переменную во время ее объявления. Java позволяет сделать это и позже.
Во-первых, можно объявлять переменные через запятую (если они одинакового типа):
При этом, смотрите, мы можем некоторые из них инициализировать прямо во время объявления. А теперь инициализируем оставшиеся:
Для инициализации переменных типа char я использовал цепочку присваиваний. Да, и так тоже можно. Хотя используется очень редко.
Если мы попытаемся провести какую-то операция с переменной, у которой нет значения, то получим ошибку.
Оператор присваивания
Литералы
В Java постоянные значения задаются литеральным представлением. Простым языком, при помощи определенных символов мы можем указывать тип данных. Вот например, при работе с целочисленными литералами нам не нужны никакие литералы. Мы просто пишем число 1998; и Java понимает, что это целочисленное значение.
Так, что еще за символы подчеркивания в значении переменной? Это всего-навсего декор. С JDK 7 допустимо указывать знаки подчеркивания, для разбиения больших чисел на разряды, для удобства чтения.
В вышеописанных примерах были литералы для целочисленных десятичных значений. А еще мы можем присвоить целому числу литерал в виде восьмеричного значения. Для этого вам нужно добавить в самом начале значения 0. Но в таком случае, логично, что это значение не сможет содержать цифры 8 и 9, поскольку они выходят за пределы восьмеричной системы счисления.
Мало того, еще мы можем использовать литерал шестнадцатеричных значений. Такие значения обозначают с начальным 0x или 0X, а цифры в пределах от 10 до 15 заменяются символами ABCDEF английского алфавита.
С JDK 7 есть возможность указывать целочисленные литералы в двоичном виде. Для этого вначале значения нужно указать 0b или 0B и соответственно в значениях можно использовать только цифры 0 и 1. В реальности, вам навряд ли понадобятся литералы шестнадцатеричных, восьмеричного или двоичных значений. Однако, знать о них нужно.
Литералы дробных чисел
Но существует и экспоненциальная форма записи этих чисел в виде 2.34e12;
Где число после символа ‘e’ обозначает степень 10-ти. Простыми словами, мы записали 2 целых и 34 сотых умноженное на 10 в 12 степени.
Как и в случае с целочисленными значениями, литералы с плавающей точкой поддерживают нижнее подчеркивание начиная с JDK 7.
Логические литералы
Символьные литералы
Для символьных литералов, которые присутствуют на вашей клавиатуре вы можете использовать одинарные кавычки, обернув ими необходимый вам символ введенный с клавиатуры.
Я не просто так обратил ваше внимание на символы с клавиатуры. Ведь существуют и такие символы, которых на клавиатуре нет, да и на символы они не похожи. Сейчас разберемся.
А вот если символ нельзя ввести непосредственно с клавиатуры, то для ввода таких символов используют ряд управляющих последовательностей. Например, символ переноса строки ‘\n’. Существуют последовательности, которые существуют для ввода значений в восьмеричной и шестнадцатеричной форме. Например, мы захотели ввести букву tu катаканы смайлик: ツ. Берем и пишем:
В данной таблице вы можете посмотреть наиболее используемые последовательности символов:
Когда-то давно, я писал статью про экранирование символом. Настоятельно рекомендую прочитать, как дополнительный материал. Узнаете много интересного.
Строковый литерал
Можно заключить последовательность символов в двойные кавычки и получить так называемую строку.
Динамическая инициализация
Пару слов о таком термине как динамическая инициализация. Ничего сложного, только звучит страшно.
Переменную можно инициализировать другой переменной. Также, допускается инициализация переменной результатом какого-то выражения.
Главное, чтобы тип данных выражения / инициализирующей переменной совпадал с типом данных целевой переменной.
Преобразование и приведение типов
Знаю, вы уже подустали, сделали массу перерывов и подходов. Обещаю, это последняя тема в этой статье.
Часто программисты сталкиваются с ситуацией, когда переменной одного типа приходится присваивать значение другого типа. Если оба типа данных совместимы, их преобразование будет выполнено автоматически. Для автоматического преобразования должно выполняться 2 условия:
Чтобы выполнить преобразование двух несовместимых типов данных, нужно воспользоваться приведением типов. Это явное преобразование одного типа в другой. И выглядит это вот так:
Нужно понимать, что преобразование вы проводите на свой страх и риск. Вы должны быть уверенным в том, что преобразуемое значение помещается в диапазон целевого типа. В противном случае вы получите некорректные данные.
Подводим итоги
В этой статье мы поговорили о многих важных вещах. Узнали, как создавать переменные и константы в Java, и чем они отличаются. Узнали о способах инициализации переменных. Разобрались с тем, что такое литералы и какие они бывают. А так же выполнили преобразование и приведение типов данных.
Скажем спасибо Егору за предоставленный материал.