Введение: Почему даже гении ошибаются в Java?
Java — строгий, но благодарный язык. Однако новички часто спотыкаются на одних и тех же граблях. По статистике Stack Overflow, 70% вопросов от начинающих Java-разработчиков связаны с пятью классическими ошибками. В этой статье мы собрали «Топ ошибок начинающих Java разработчиков: от А до Я» — от путаницы с == до неправильной работы с памятью.
Мы разберём каждую проблему на примерах, чтобы вы не просто запомнили правило, а поняли его суть. Поехали!
1. Ошибка №1: «==» вместо equals() — классика жанра
Самая популярная ошибка — сравнение строк через ==. Новички думают, что это работает, а потом удивляются, почему "Java" == "Java" даёт false.
Почему так происходит?
==сравнивает ссылки на объекты (адреса в памяти).equals()сравнивает содержимое объектов.
Пример:
String a = new String("Java");
String b = new String("Java");
System.out.println(a == b); // false — разные объекты в куче
System.out.println(a.equals(b)); // true — одинаковое содержимое
Совет: Всегда используйте .equals() для строк. Для примитивов (int, double) — == работает корректно.
2. Ошибка №2: Забываем про NullPointerException
NullPointerException (NPE) — злейший враг джуниора. Чаще всего возникает, когда вы вызываете метод на null.
Типичный сценарий:
public String getName(User user) {
return user.getName().toUpperCase(); // Если user == null — NPE!
}
Как исправить? Используйте защитное программирование:
public String getName(User user) {
if (user == null) {
return "Unknown";
}
return user.getName().toUpperCase();
}
Или, начиная с Java 8, — Optional:
public String getName(User user) {
return Optional.ofNullable(user)
.map(u -> u.getName().toUpperCase())
.orElse("Unknown");
}
3. Ошибка №3: Игнорирование исключений
Пустые catch-блоки — это антипаттерн. Ошибка не исчезает, вы просто её прячете.
Плохой код:
try {
int result = 10 / 0;
} catch (ArithmeticException e) {
// Ничего не делаем — ошибка молча проглатывается
}
Хороший код:
try {
int result = 10 / 0;
} catch (ArithmeticException e) {
System.err.println("Ошибка деления на ноль: " + e.getMessage());
// Или пробрасываем исключение дальше
throw new RuntimeException("Критическая ошибка", e);
}
4. Ошибка №4: Неправильная работа с коллекциями
Новички часто путают List, Set и Map, а ещё забывают про дженерики.
Типичные ляпы:
- Использование сырых типов (raw types) —
List list = new ArrayList(); - Изменение коллекции во время итерации без
Iterator.remove() - Замена
HashMapнаTreeMapбез понимания разницы
Правильный подход:
List<String> names = new ArrayList<>();
names.add("Alice");
names.add("Bob");
// Удаление во время итерации
Iterator<String> iterator = names.iterator();
while (iterator.hasNext()) {
String name = iterator.next();
if (name.equals("Alice")) {
iterator.remove(); // Безопасно
}
}
5. Ошибка №5: Утечка памяти и неправильное закрытие ресурсов
Забываете закрывать Scanner, FileInputStream или соединение с БД? Это приводит к утечкам.
До Java 7 (кошмар):
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader("file.txt"));
System.out.println(br.readLine());
} finally {
if (br != null) {
br.close(); // Легко забыть
}
}
После Java 7 (красота):
try (BufferedReader br = new BufferedReader(new FileReader("file.txt"))) {
System.out.println(br.readLine());
} // Ресурс закроется автоматически
Используйте try-with-resources — это спасёт вашу память (буквально).
6. Ошибка №6: Путаница с модификаторами доступа
Новички часто делают все поля public «для удобства». Это нарушает инкапсуляцию.
Плохо:
public class User {
public String name; // Любой может изменить
public int age;
}
Хорошо:
public class User {
private String name;
private int age;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
// Геттеры и сеттеры — контроль доступа
}
7. Ошибка №7: Неправильное использование статических методов
Статика — это не «магия для всех случаев». Частая ошибка: обращение к нестатическому полю из статического метода.
public class Counter {
private int count = 0; // Нестатическое поле
public static void increment() {
count++; // Ошибка компиляции!
}
}
Помните: Статические методы видят только статические поля и другие статические методы.
8. Ошибка №8: Забываем про equals() и hashCode()
Если вы переопределяете equals(), обязательно переопределите и hashCode(). Иначе объекты вашего класса не смогут корректно работать в HashMap или HashSet.
public class Person {