- Литералы
- Литералы с плавающей точкой
- Символьные литералы
- Строковые литералы
- Булевы литералы
- JDK 7
- 5 особенностей языка Java, о которых вы должны знать
- Инструкции можно переставлять
- В числовых значениях можно использовать нижние подчеркивания
- Автоупаковка целочисленных кэшируется
- Файлы языка Java могут содержать множество не вложенных классов
- StringBuilder используется для конкатенации строк
- Подчеркивания в Числовых Литералах
Литералы
Целочисленные литералы — самый используемый тип в программах. Любое целочисленное значение является числовым литералом, т.е. значения 1, 5, 9, 42 и т.п. являются числовыми литералами с основанием 10. Также можно использовать восьмеричные и шестнадцатиричные значения.
Восьмиричные значения обозначаются ведущим нулем (обычные десятичные числа не могут иметь ведущий нуль). По этой причине с виду нормальное число 09 вызовет ошибку компиляции, так как выйдет за пределы диапазона от 0 до 7 допустимых восьмеричных значений.
Шестнадцатиричные значения обозначают ведущим нулём и символом x (икс). Можно использовать маленький (0x) и большой (0X) символ в числах. Диапазон допустимых цифр — от 0 до 15, где цифры от 10 до 15 заменяются буквами от A до F (можно также использовать символы от a до f в нижнем регистре).
Целочисленные литералы создают значения типа int. Если вы создали переменную типа byte или long, а значение литерала находится в диапазоне допустимых значений этих типов, то ошибки не возникает. Не возникает проблем и с типом long, у которого диапазон значений всегда больше, чем у int. Но при этом нужно явно указать, что значение литерала имеет тип long при помощи строчной или прописной буквы L. Например, 899888777666555444333L.
Целочисленное значение можно также присвоить типу char, если оно лежит в допустимых пределах.
Литералы с плавающей точкой
Числа с плавающей точкой представляют десятичные значения с дробной частью. Число можно записать в двух вариантах — в стандартной и научной форме записи. Стандартная форма — целое число, за которым следуют десятичная точка и дробная часть (например, 3.14). Научная форма записи использует стандартную форму записи числа с плавающей точкой, к которой добавлен суффикс, указывающий степенную функцию числа 10, на которую нужно умножить данное число. Для указания экспоненциальной функции используют символ E или e, за которыми следует десятичное число (положительное или отрицательное). Например, 5.07E12.
По умолчанию литералам с плавающей точкой присвоен тип double. Если вам нужен тип float, то нужно дописать символ F или f. Кстати, для double можно использовать суффиксы D или d, но в этом нет необходимости.
Также возможна запись шестнадцатиричных литерал с плавающей точкой, но на практике я не встречал подобную запись. В этом случае вместо E используется P (или p) — 0x14.3p2.
Символьные литералы
В Java символы представляют собой 16-битовые значения в наборе символов Unicode. Эти значения можно преобразовать в целые значения и применить операции сложения и вычитания. Символьные литералы обрамляются одинарными кавычками. Обычные символы можно ввести стандартным способом, например, ‘c’, ‘a’, ‘@’. Существуют также символы, которые следует экранировать обратным слешем, например, чтобы вывести сам символ одинарной кавычки, нужно использовать вариант ‘\n». Для символа новой строки используется ‘\n’.
Можно вывести нужный символ, используя его восьмеричное или шестнадцатиричное значение. При восьмеричной форме используют обратный слеш, за которым следует трёхзначный номер — ‘\143’.
Для ввода шестнадцатиричного значения используют обратный слеш, символ u, за которыми следуют четыре шестнадцатиричные цифры, например, ‘\u0061’.
Строковые литералы
Строковые литералы — это набор символов в двойных кавычках, например, «Кот — это муж кошки». Внутри строковых литералов также можно использовать управляющие символы, например, для перевода на новую строку — «Кот\nКошка\nКотёнок».
Булевы литералы
Есть только два булевых литерала — true и false. В отличие от некоторых языков программирования, эти значения не преобразуются в числовые значения. При этом литерал true не равен 1, а литерал false не равен 0.
JDK 7
Раньше Android не поддерживал JDK 7. Сейчас поддержка имеется и стали доступны новые возможности.
В JDK 7 можно использовать целочисленные литералы в двоичной системе. Для этого нужно использовать префикс 0b или 0B:
Кроме того, в JDK 7 можно вставлять символы подчёркивания для облегчения чтения больших числовых литералов:
int x = 123_456_789; double num = 8_343_398.0;
Символы подчёркивания будут проигнорированы компилятором. Учтите, что можно использовать несколько подряд символов подчёркивания, но нельзя использовать символы подчёркивания в начале или в конце литерала.
Подобная запись удобна при записи вручную программистом номеров телефонов и тому подобных вещей, чтобы визуально лучше анализировать значения. А умная железка сама разберётся, что к чему и не будет удивляться символам подчёркивания в числах.
5 особенностей языка Java, о которых вы должны знать
О некоторых особенностях языка Java порой не знают сами джависты, — говорится в статье, опубликованной сайтом proglib.io.
Рассказываем о 5 особенностях этого языка, которые должен знать каждый.
Инструкции можно переставлять
[java]int x = 1;int y = 3;
System.out.println(x + y);[/java]
Взглянув на код, мы можем предположить, что сначала значение 1 будет присвоено x, а затем значение 3 – переменной y. Но если порядок присвоения переменных изменится, конечный результат окажется тем же: мы увидим в выводе 4. Используя это наблюдение, компилятор может безопасно изменить порядок этих двух операций присваивания в случае необходимости. Когда мы компилируем код, компилятор делает именно это: он может свободно переупорядочивать инструкции, если это не изменяет ожидаемое поведение системы.
И хотя перестановка в примере выше не приведет ни к каким положительным изменениям, есть ситуации, когда изменение порядка инструкций повысит производительность. Предположим, в нашем коде переменные x и y дважды увеличиваются в процессе чередования.
[java]int x = 1;int y = 3;
x++;
y++;
x++;
y++;
System.out.println(x + y);
[/java]
Этот код должен вывести 8, и он сделает это даже при изменении порядка операций. В процессе оптимизации компилятор может полностью избавить код от операций приращения:
[java]// Смена порядка инструкцийint x = 1;
int y = 3;
x++;
x++;
y++;
y++;
System.out.println(x + y);
// Сжатие инструкций
int x = 1;
int y = 3;
x += 2;
y += 2;
System.out.println(x + y);
// Полное сжатие инструкций
int x = 3;
int y = 5;
System.out.println(x + y);[/java]
В действительности, компилятор продвинется еще на шаг дальше и переместит значения x и y сразу в print.
В числовых значениях можно использовать нижние подчеркивания
Читать большие числа неудобно. Для удобства чтения в математике их принято разделять точкой: вместо 1183548876845 получается вполне читабельное 1.183.548.876.845.
К сожалению, в коде языка Java часто встречаются огромные числа в виде констант, как в примере ниже.
[java]public class Foo public static final long LARGE_FOO = 1183548876845l;>
System.out.println(LARGE_FOO);[/java]
Конечно, содержимое констант редко претендует на эстетичность, но разбирать такое число глазами не очень удобно. К счастью, в Java Development Kit (JDK) седьмой версии появилась возможность разделять числа с помощью нижнего подчеркивания ( _ ) так же, как мы привыкли делать это с помощью точки.
[java]public class Foo public static final long LARGE_FOO = 1_183_548_876_845l;>
System.out.println(LARGE_FOO);[/java]
Таким же образом, кстати, можно разделять и длинные хвосты десятичных дробей.
[java]public static final double LARGE_BAR = 1.546_674_876;[/java]Автоупаковка целочисленных кэшируется
В Java мы можем записать целочисленное значение следующим образом:
[java]Integer myInt = 500;[/java]Примитив int 500 преобразуется в объект типа Integer и сохраняется в myInt. Такая обработка называется автобоксинг или автоупаковка, поскольку преобразование примитива в объект типа Integer происходит автоматически.
Так как myInt является объектом типа Integer, мы ожидаем, что сравнение его с другим объектом того же типа и содержащего то же значение с помощью оператора == приведет к false. Но вызов сравнения для этих двух объектов приведет к true, так как оба объекта представлены одним значением – 500:
[java]Integer myInt = 500;Integer otherInt = 500;
System.out.println(myInt == otherInt); // false
System.out.println(myInt.equals(otherInt)); // true[/java]
На этом этапе autoboxing работает точно так, как ожидается, но что произойдет, если мы попробуем это с меньшим числом? Например, 25:
[java]Integer myInt = 25;Integer otherInt = 25;
System.out.println(myInt == otherInt); // true
System.out.println(myInt.equals(otherInt)); // true[/java]
Тут мы увидим, что оба объекта равны как по ==, так и по equals. Это означает, что два объекта Integer, фактически являются одним объектом. Такое странное поведение, на самом деле, не является ни ошибкой, ни недосмотром: оно было допущено умышленно. Поскольку многие операции автобоксинга выполняются с небольшими числами (до 127), JLS говорит о том, что значения Integer в диапазоне от -128 до 127 включительно кэшируются.
Файлы языка Java могут содержать множество не вложенных классов
В одном файле исходного кода может разместиться множество не вложенных классов, которые не являются public. Для них уровень доступа будет установлен как package-private (то есть, без модификатора доступа). При этом, в каждом файле может содержаться только один public класс.
После компиляции количество файлов будет равно количеству не вложенных классов.
StringBuilder используется для конкатенации строк
Конкатенация строк присутствует почти во всех языках программирования и позволяет соединять между собой строки или объекты и примитивы разных типов в одну строку. Одна из сложностей конкатенации в Java – неизменяемость строк. То есть мы не можем все время добавлять данные к одной и той же строке. Каждый append будет создавать новый объект String и продолжать работу с ним.
Это не критично, когда нужно произвести конкатенацию нескольких строк, но когда объемы вырастают до, скажем, 1000 строк, эта техника становится нестабильной, да и создавать тысячу сущностей String довольно расточительно.
Однако документация JLS сообщает, что подобного можно избежать. Для этого нужно использовать StringBuilder, который поработает как буфер. Строка, к которой идет присоединение других строк, будет существовать до тех пор, пока она нужна. Таким образом, при конкатенации будет существовать всего одна сущность String.
Для примера, соединение строк с помощью StringBuilder в цикле выглядит так:
[java]StringBuilder builder = new StringBuilder();for (int i = 0; i < 1000; i++) builder.append("a");
>
String myString = builder.toString();[/java]
Подчеркивания в Числовых Литералах
В Java SE 7 и позже, любое число символов подчеркивания ( _ ) может появиться где угодно между цифрами в числовом литерале. Эта опция позволяет Вам, например, разделить группы цифр в числовых литералах, которые могут улучшить удобочитаемость Вашего кода.
Например, если Ваш код содержит числа со многими цифрами, можно использовать символ подчеркивания, чтобы разделить цифры в группах три, подобный тому, как Вы использовали бы знак препинания как запятая, или пространство, как разделитель.
Следующий пример показывает другие способы, которыми можно использовать подчеркивание в числовых литералах:
long creditCardNumber = 1234_5678_9012_3456L; long socialSecurityNumber = 999_99_9999L; float pi = 3.14_15F; long hexBytes = 0xFF_EC_DE_5E; long hexWords = 0xCAFE_BABE; long maxLong = 0x7fff_ffff_ffff_ffffL; byte nybbles = 0b0010_0101; long bytes = 0b11010010_01101001_10010100_10010010;
Можно поместить подчеркивания только между цифрами; невозможно поместить подчеркивания в следующие места:
- Вначале или конец числа
- Смежный с десятичной точкой в литерале с плавающей точкой
- До F или L суффикс
- В позициях, где строка цифр ожидается
Следующие примеры демонстрируют допустимые и недопустимые размещения подчеркивания (которые выделяются) в числовых литералах:
float pi1 = 3_.1415F; // Invalid; cannot put underscores adjacent to a decimal point float pi2 = 3._1415F; // Invalid; cannot put underscores adjacent to a decimal point long socialSecurityNumber1 = 999_99_9999_L; // Invalid; cannot put underscores prior to an L suffix int x1 = _52; // This is an identifier, not a numeric literal int x2 = 5_2; // OK (decimal literal) int x3 = 52_; // Invalid; cannot put underscores at the end of a literal int x4 = 5_______2; // OK (decimal literal) int x5 = 0_x52; // Invalid; cannot put underscores in the 0x radix prefix int x6 = 0x_52; // Invalid; cannot put underscores at the beginning of a number int x7 = 0x5_2; // OK (hexadecimal literal) int x8 = 0x52_; // Invalid; cannot put underscores at the end of a number int x9 = 0_52; // OK (octal literal) int x10 = 05_2; // OK (octal literal) int x11 = 052_; // Invalid; cannot put underscores at the end of a number