Pull to refresh

Малоизвестные особенности Java. Вторая часть

Reading time 3 min
Views 58K
Как и обещал, предлагаю вашему вниманию следующие пять пунктов.

Малоизвестные особенности Java. Первая часть

6. Конфликт имён.

Если импортированы несколько классов с одним и тем же именем из разных пакетов, возникает конфликт имён. В таком случае при обращении к классу следует указывать его квалифицированное имя, то есть полное имя, включая и имя пакета, например java.lang.String.

Неужели ничего нельзя с этим поделать? Оказывается можно. Следующий код скомпилируется без проблем, несмотря на то, что класс List присутствует и в пакете java.awt, и в пакете java.util:

import java.awt.*;
import java.util.*;
import java.util.List;

public class Класс {
	public static void main(String... аргументы) {
		List простоСписок = Collections.emptyList();
		System.out.println(простоСписок);
	}
}


Достаточно дополнительно импортировать необходимый класс, java.util.List в данном примере.

Тут, как вы заметили, используются кириллические идентификаторы. Да! Для кого-то это станет откровением, но Java… такая Java. Идентификатор может состоять из совершенно любых букв, помимо цифр, знаков подчёркивания и валюты США (однако последний знак ($) использовать не рекомендуется, он предназначен для системных нужд). Но оно нам надо? Разве только в целях обфускации. Только представьте себе, сколько разных идентификаторов можно сгенерировать всего-то из символов «А» английского, русского и греческого алфавитов…



7. Инициализация коллекций.

К каким только хитростям не приходится прибегать, чтобы упростить инициализацию коллекций и облегчить восприятие кода. Благодаря переменному числу аргументов в методе (varargs), которое появилось в пятой версии SDK, а также заботливому обновлению разработчиками стандартного API, ситуация стала немного лучше:

List<Integer> theNumbers = new LinkedList<Integer>();
Collections.addAll(theNumbers, 4, 8, 15, 16, 23, 42);


Но этот код занимает две строки вместо одной и не кажется логически связанным. Можно использовать сторонние библиотеки, такие как Google Collections, или изобрести свой велосипед, но есть и более опрятный вариант:

List<Integer> theNumbers = new LinkedList<Integer>(Arrays.asList(4, 8, 15, 16, 23, 42));


А с появлением статического импорта во всё той же версии Java можно укоротить эту конструкцию ещё на одно слово:

import static java.util.Arrays.*;

// ...

List<Integer> theNumbers = new LinkedList<Integer>(asList(4, 8, 15, 16, 23, 42));


Впрочем, если число элементов в коллекции изменяться не будет, мы можем написать совсем просто:

import static java.util.Arrays.*;

// ...

List<Integer> theNumbers = asList(4, 8, 15, 16, 23, 42);


Эти приёмы позволяют инициализировать коллекции-наследники интерфейса Collection, простите за каламбур, но с картами так не получится, к сожалению. Хотя решение есть, смотрите предыдущую часть статьи.

8. Подсписки.

Интерфейс java.util.List, от которого наследуются в частности ArrayList и LinkedList, обладает замечательным методом: List.subList(). Он возвращает не новый список, как может показаться, а вид (view) списка, для которого этот метод был вызван, таким образом, что оба списка станут разделять хранимые элементы. Из этого вытекают прекрасные свойства:

someList.subList(3, 7).clear();


В данном примере из списка someList будут удалены четыре элемента, с третьего по седьмой (не включительно).

Подсписки можно использовать в качестве диапазонов (ranges), которые являются довольно мощной идиомой программирования. Как часто вам требовалось обойти коллекцию, исключая первый или последний элемент, например? Теперь foreach становится ещё мощнее:

import static java.util.Arrays.*;

// ...

List<Integer> theNumbers = asList(4, 8, 15, 16, 23, 42);
int size = theNumbers.size();
for (Integer number : theNumbers.subList(0, size - 1)) {
	System.out.print(number + ", ");
}
System.out.println(theNumbers.get(size - 1));


Подсписки следует использовать с осторожностью из-за особенностей, вытекающих из их сути (для подробностей смотрите документацию).

9. Cafe babe.

Все скомпилированные классы и интерфейсы хранятся в специальных файлах с расширением .class. В них содержится байт-код, интерпретируемый виртуальной машиной Java. Чтобы быстро распознавать эти файлы, в них, в первых четырёх байтах, содержится метка, которая в шестнадцатеричном виде выглядит так: 0xCAFEBABE.

Ну с первым словом всё ясно — Java, как известно, названа была не в честь тропического острова, а одноимённого сорта кофе, и среди знаков, используемых в шестнадцатеричной системе cчисления, литер «J» и «V» не нашлось. А вот чем руководствовались разработчики, выдумывая второе слово, остаётся только догадываться:)

10. Исключительные ситуации.

И напоследок небольшой кусочек кода:

try {
	throw null;
} finally {
	return;
}


Здесь выбрасывается NullPointerException и… теряется, исчезает без следа! Будьте бдительны.
Tags:
Hubs:
+55
Comments 42
Comments Comments 42

Articles