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

1
14441
Добавить в избранное

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

Инструкции можно переставлять

Рассмотрим пример:

Взглянув на код, мы можем предположить, что сначала значение 1 будет присвоено x, а затем значение 3 – переменной y. Но если порядок присвоения переменных изменится, конечный результат окажется тем же: мы увидим в выводе 4. Используя это наблюдение, компилятор может безопасно изменить порядок этих двух операций присваивания в случае необходимости. Когда мы компилируем код, компилятор делает именно это: он может свободно переупорядочивать инструкции, если это не изменяет ожидаемое поведение системы.

И хотя перестановка в примере выше не приведет ни к каким положительным изменениям, есть ситуации, когда изменение порядка инструкций повысит производительность. Предположим, в нашем коде переменные x и y дважды увеличиваются в процессе чередования.

Этот код должен вывести 8, и он сделает это даже при изменении порядка операций. В процессе оптимизации компилятор может полностью избавить код от операций приращения:

В действительности, компилятор продвинется еще на шаг дальше и переместит значения x и y сразу в print.

В числовых значениях можно использовать нижние подчеркивания

Читать большие числа неудобно. Для удобства чтения в математике их принято разделять точкой: вместо 1183548876845 получается вполне читабельное 1.183.548.876.845.

К сожалению, в коде языка Java часто встречаются огромные числа в виде констант, как в примере ниже.

Конечно, содержимое констант редко претендует на эстетичность, но разбирать такое число глазами не очень удобно. К счастью, в Java Development Kit (JDK) седьмой версии появилась возможность разделять числа с помощью нижнего подчеркивания ( _ ) так же, как мы привыкли делать это с помощью точки.

Таким же образом, кстати, можно разделять и длинные хвосты десятичных дробей.

Автоупаковка целочисленных кэшируется

В Java мы можем записать целочисленное значение следующим образом:

Примитив int 500 преобразуется в объект типа Integer и сохраняется в myInt. Такая обработка называется автобоксинг или автоупаковка, поскольку преобразование примитива в объект типа Integer происходит автоматически.

Так как myInt является объектом типа Integer, мы ожидаем, что сравнение его с другим объектом того же типа и содержащего то же значение с помощью оператора == приведет к false. Но вызов сравнения для этих двух объектов приведет к true, так как оба объекта представлены одним значением – 500:

На этом этапе autoboxing работает точно так, как ожидается, но что произойдет, если мы попробуем это с меньшим числом? Например, 25:

Тут мы увидим, что оба объекта равны как по ==, так и по equals. Это означает, что два объекта Integer, фактически являются одним объектом. Такое странное поведение, на самом деле, не является ни ошибкой, ни недосмотром: оно было допущено умышленно. Поскольку многие операции автобоксинга выполняются с небольшими числами (до 127), JLS говорит о том, что значения Integer в диапазоне от -128 до 127 включительно кэшируются.

Файлы языка Java могут содержать множество не вложенных классов

В одном файле исходного кода может разместиться множество не вложенных классов, которые не являются public. Для них уровень доступа будет установлен как package-private (то есть, без модификатора доступа). При этом, в каждом файле может содержаться только один public класс.

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

StringBuilder используется для конкатенации строк

Конкатенация строк присутствует почти во всех языках программирования и позволяет соединять между собой строки или объекты и примитивы разных типов в одну строку. Одна из сложностей конкатенации в Java – неизменяемость строк. То есть мы не можем все время добавлять данные к одной и той же строке. Каждый append будет создавать новый объект String и продолжать работу с ним.

Это не критично, когда нужно произвести конкатенацию нескольких строк, но когда объемы вырастают до, скажем, 1000 строк, эта техника становится нестабильной, да и  создавать тысячу сущностей String довольно расточительно.

Однако документация JLS сообщает, что подобного можно избежать. Для этого нужно использовать StringBuilder, который поработает как буфер. Строка, к которой идет присоединение других строк, будет существовать до тех пор, пока она нужна. Таким образом, при конкатенации будет существовать всего одна сущность String.

Для примера, соединение строк с помощью StringBuilder в цикле выглядит так:

Больше о возможностях языка Java:

 

Интересуетесь программированием на Java?

Подпишитесь на нашу рассылку, чтобы получать больше интересных материалов:

И не беспокойтесь, мы тоже не любим спам. Отписаться можно в любое время.




Один комментарий

  1. Насчет последнего пункта еще добавлю, что StringBuilder работает гораздо быстрее, чем String.format — многие, даже senior’ы, этого факта не знают.

Добавить комментарий