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

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

О некоторых особенностях языка 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 включительно кэшируются.

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

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

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

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

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

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

proglib.io

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

Ваш e-mail не будет опубликован.

восемнадцать + 6 =