5 особенностей языка Java, о которых вы должны знать

О некоторых особенностях языка Java порой не знают сами джависты, —  говорится в статье, опубликованной сайтом proglib.io.

Особенности языка Java

Рассказываем о 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 класс.

[java]public class Foo {
//…
}

class Bar {
//…
}

class Bar1 {
//…
}[/java]

После компиляции количество файлов будет равно количеству не вложенных классов.

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]


[customscript]techrocks_custom_after_post_html[/customscript]
[customscript]techrocks_custom_script[/customscript]

2 комментария к “5 особенностей языка Java, о которых вы должны знать”

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Прокрутить вверх