Давно собирался собрать коллекцию анти-паттернов, дабы самому просвятиться и другим помочь. Данную заметку буду периодически пополнять, по мере нахождения последних.
Итак, азы! :)
Конкатенация строк
for (Item i : items) {
s += ", " + i.getText();
}
Во-первых, конкатенация строк дело плохое, т.к. при этом образуется новый объект строки. Во-вторых, конкатенация в цикле приведет к тому, что для получения единственной конечной строки образуется items.length2 новых мусорных объектов.
Вместо конкатенации необходимо использовать StringBuffer (или даже лучше StringBuilder, если не нужна "thread safe"). При этом, выражения типа stringBuffer.append("val=" + value); естественно приведут к полной бесполезности использования StringBuffer'а.
Сравнение строк
Еще один пример anti-pattern'а - это сравнение строк. Сделать это можно так:
Последний вариант хоть и является более правильным, но все же не идеал. Наиболее корректный подход - это
В данном случае мы избежим NullPointerException (если str == null), а также, если сравнение происходит в цикле - метод equals будет вызываться у одного и того же объекта.
URL.equals...
Не используйте для сравнения java.net.URL метод equals, т.к. последний говорит true, если сравнивыемые хосты url'ов имеют одинаковый IP адрес. Например:
URL b = new URL("http", "stremoukhov.com", "index.php");
System.out.println(a.equals(b)); // Выведет true!
Вместо этого можно использовать
java.net.URI
Переопределение equals()
При переопределении метода equals() необходимо помнить, что понадобится переопределить hashcode() дабы они не противоречили друг другу, а также, в реализации метода не забыть сделать проверку на instanceof (которая также обезопасит от NullPointerException):
return (obj instanceof UserType) && this.id.equals(((UserType)obj).getId());
}
Создание immutable объектов
Тут все просто - незачем создавать новый immutable-объект, теряя время и ресурсы на его инициализацию и размещение в памяти. В качестве примера можно взять обертки примитивных типов. Статический метод valueOf() будет работать гораздо быстрее.
Integer i = new Integer(0);
Boolean b = new Boolean(true);
// Правильно будет:
Integer i = Integer.valueOf(0);
Boolean b = Boolean.TRUE;
Небуфферизированные потоки
Многие разработчики читают и записывают потоки по байтам, используя стандартные FileInputStream и FileOutputStream. Например:
int i;
while ((i = in.read()) != -1) {
}
Такой подход плох тем, что каждый вызов in.read(), а точнее, чтение каждого байта порождает обращение к JNI (Java Native Interface). Намного эффективнее будет использовать Buffered Streams:

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