🔥 🚀 Важно для всех, кто работает с Java! 🔥
На JavaRocks ты найдешь уникальные туториалы, практические задачи и редкие книги, которых не найти в свободном доступе. Присоединяйся к нашему Telegram-каналу JavaRocks — стань частью профессионального сообщества!
В этой статье разберём 8 самых распространенных ошибок, которые допускают начинающие (и не только) Java-разработчики. В сети можно найти множество подобных списков — многие из них довольно похожи между собой.
Список не отсортирован по важности — они все одинаково важны для понимания и их стоит запомнить.
Ошибка 1. Сравнение объектов с помощью ==
Оператор ==
сравнивает ссылки на объекты, а не их содержимое.
Ссылки указывают на адреса в памяти. Если два объекта находятся по разным адресам, то сравнение с помощью ==
вернет false.
public class Vehicle {
String model;
int maxSpeed;
int yearOfManufacture;
public Car(String model, int maxSpeed, int yearOfManufacture) {
this.model = model;
this.maxSpeed = maxSpeed;
this.yearOfManufacture = yearOfManufacture;
}
public static void main(String[] args) {
Car ferrari = new Car("Ferrari 360 Spider", 280, 1996);
Car ferrariTwin = new Car("Ferrari 360 Spider", 280, 1996);
System.out.println(ferrari == ferrariTwin);
}
}
Run CodeДля сравнения объектов в классе Object
есть специальный метод: equals()
. Если честно, его стандартная реализация неплоха:
public boolean equals(Object obj) {
return (this == obj);
}
Run CodeВ самом классе Object
метод equals()
реализован как сравнение двух ссылок. Чтобы корректно сравнивать объекты, необходимо переопределить этот метод с учетом критериев равенства, которые актуальны в конкретной программе для конкретных объектов. Какие именно это будут критерии — вы решаете сами.
Единственное, о чем нельзя забывать, — это список требований для правильного переопределения equals()
. Их легко можно найти в Интернете.
Ошибка 2. Использование нестатических переменных в статических методах (и наоборот)
Если вы когда-нибудь видели сообщение “Non-static variable x cannot be referenced from a static context”, добро пожаловать в клуб 🙂
У статических методов нет доступа к нестатическим (экземплярным) переменным.
Это логично: статический метод можно вызвать без создания объекта класса, а нестатические поля принадлежат конкретным объектам. Именно в этом и заключается противоречие, которое приводит к ошибке.
А в обратную сторону всё работает нормально: в нестатических методах можно спокойно обращаться к статическим переменным.
public class Main {
public int x = 10;
public static int staticX = 100;
public static void main(String[] args) {
System.out.println(x); // Compilation error - you can't do this!
}
public void printX() {
System.out.println(staticX); // But you can do this!
}
}
Run CodeОшибка 3. Непонимание механизма передачи аргументов в методы: по ссылке или по значению
В Java объекты и примитивы передаются в методы по-разному: первые — по ссылке, вторые — по значению.
Для новичков этот момент часто оказывается сложным для понимания. В результате код ведет себя не так, как ожидалось:
public class Main {
public static void main(String[] args) {
int x = 7;
incrementNumber(x);
System.out.println(x);
Cat cat = new Cat(7);
catLevelUp(cat);
System.out.println(cat.getAge());
}
public static void catLevelUp(Cat cat) {
cat.setAge(cat.getAge()+1);
}
public static void incrementNumber(int x) {
x++;
}
}
Run CodeЕсли вы не знаете, какое именно число будет увеличиваться, а какое нет (простое число или возраст кошки), то прочитайте эту статью.
Ошибка 4. Игнорирование правил кодирования
Это относится не только к соблюдению определенных “технических” принципов, но и к обычным соглашениям о наименованиях.
Все эти правила (как называть переменные, как писать имена методов) придуманы не просто так. Они действительно влияют на читаемость кода.
В конце концов, код — не всегда будет принадлежать только вам. Вас могут перевести на другой проект внутри компании, а коллегам, которые унаследуют ваш код, вряд ли будет приятно увидеть нечто подобное:
public class Cat {
private int S_O_M_E_T_H_I_N_G = 7;
public String striiiiiiiiiiiiiing;
protected double I_HAVE_NO_IDEA_WHAT_THIS_IS = 3.14;
boolean random = Math.random() > 0.5;
}
Run CodeДаже если ваш код суперэффективный, но невозможно прочитать и понять, как он работает, то, увы, толку от него немного.
Если вы придерживаетесь стандартов кодирования, то даже неидеальный код будет понятен более опытным коллегам. А значит, они смогут подсказать, как его улучшить 🙂
Ошибка 5. Непонимание класса String
public class Main {
public static void main(String[] args) {
String s1 = "I'm learning Java";
String s2 = new String("I'm learning Java");
System.out.println(s1 == s2);
}
}
Run CodeЕсли вы не понимаете, почему этот код выводит false
, то вам явно нужно подтянуть теорию 🙂
Новички часто не знают о существовании String Pool
и принципах его работы. В результате они не совсем понимают, как правильно сравнивать строки в своем коде.
Ошибка 6. Неправильная обработка исключений
С этой проблемой сталкиваются не только новички, но и опытные разработчики. Причин тому множество.
Во-первых, не существует универсального рецепта: ошибки бывают самые разные, и сценарии обработки — тоже.
Во-вторых, не все до конца понимают, как устроен стек вызовов (stack trace
). Существует множество антипаттернов обработки ошибок, и каждый из них по-своему “неправильный”. Это значит, что ошибиться в обработке ошибок гораздо проще, чем кажется.
Ошибка 7. Непонимание механики операторов в Java: арифметических, логических и т.д.

Вот простой пример. Можете сразу сказать, что выведет этот код?
public class Main {
public static void main(String[] args) {
int i = 6;
System.out.println(7 == i++);
}
}
Run CodeЕсли вы ответили неправильно или просто угадали, значит, вам следует подтянуть свои знания 🙂
Код выведет false
. Сначала выполняется сравнение 7 == i
, а уже потом выполняется операция i++
.
На эту тему вы можете почитать эту статью.
Ошибка 8. Пропущенный break
в конструкции switch
Наверняка почти каждый, кто работает с Java, совершал эту ошибку 🙂
public class Main {
public static void main(String[] args) {
int i = 1;
switch (i) {
case 1: {
System.out.println("The number is equal to 1");
}
case 2: {
System.out.println("The number is equal to 2");
}
case 3: {
System.out.println("The number is equal to 3");
}
}
}
}
Run CodeВ результате выполнение перебирает все возможные варианты.
Вывод:
The number is equal to 1
The number is equal to 2
The number is equal to 3
Оператор break
прерывает выполнение конструкции switch
, как только нужный блок завершен. Если забыть его — можно получить совсем не то, что ожидалось 🙂
Перевод статьи «8 common mistakes made by rookie programmers».