Сравнение объектов с помощью
==
.Оператор
==
сравнивает ссылки объектов.Ссылки указывают на адреса в памяти, и если они находятся по разным адресам, сравнение через
==
будет возвращатьfalse
.public class Car { 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); } }
Для сравнения объектов в классе
Object
есть специальный метод —equals()
. Его реализация по умолчанию, прямо скажем, так себе:public boolean equals(Object obj) { return (this == obj); }
В самом классе
Object
логика методаequals()
реализована как сравнение двух ссылок. В свою очередь, для корректного сравнения объектов тебе необходимо переопределить этот метод в соответствии с теми критериями, которые важны в конкретной программе для конкретных объектов. Критерии равенства определяешь ты сам.Единственное, о чем не стоит забывать, — список требований для правильного переопределения
equals()
. Ты их легко найдешь в Интернете, но наши крутые ученики уже сделали статью на эту тему.Использование нестатических переменных в статических методах (и наоборот).
Если ты хоть раз видел надпись «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);//ошибка компиляции, так нельзя! } public void printX() { System.out.println(staticX);//а так можно! } }
Непонимание того, как передаются параметры в методы: по ссылке или по значению.
Объекты и примитивы передаются в методы в качестве параметров по-разному: первые — по ссылке, вторые — по значению.
Новичкам часто бывает сложно понять эту концепцию, в результате их код ведет себя неожиданно:
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++; } }
Если в этом примере ты точно не знаешь, какое число увеличится, а какое нет (обычное число или возраст кота), тогда перечитай еще раз нашу лекцию на эту тему.
Игнорирование правил написания кода.
И это касается не только соблюдения тех или иных «технических» принципов, но и банальных соглашений об именовании.
Все эти правила «как надо называть переменные», «как надо писать названия методов» были придуманы не просто так. Это и правда сильно влияет на читаемость кода.
Ведь код не всегда будет только твоим. Ты можешь перевестись на другой проект в компании, и он перейдет по наследству к твоим коллегам, которые будут явно не в восторге, получив в работу что-то вроде этого:
public class Cat { private int S_O_M_E_T_H_I_N_G = 7; public String striiiiiiiiiiiiiing; protected double X3_4TO_ET0_TAK0E = 3.14; boolean random = Math.random() > 0.5; }
Твой код может быть гениальным с точки зрения производительности, но если его невозможно прочитать и понять как он, собственно, работает, цена его, увы, невелика.
Придерживайся стандартов написания, и твой код, даже далекий от идеала, хотя бы прочтут более опытные товарищи и подскажут, что с технической точки зрения в нем можно улучшить :)
Непонимание работы класса
String
public class Main { public static void main(String[] args) { String s1 = "Я изучаю Java"; String s2 = new String("Я изучаю Java"); System.out.println(s1 == s2); } }
Если ты не знаешь, почему этот код выводит
false
, знания явно нужно подтянуть:)Новички часто не знают что такое
String Pool
и как он работает.Как следствие, не до конца ясно, как правильно сравнивать строки в своем коде. В одной из наших лекций мы подробно рассматривали эту тему
Неправильная работа с исключениями.
Это свойственно не только новичкам, но и опытным разработчикам. Причин несколько.
Во-первых, универсального рецепта не существует. Ошибки в программе бывают разные, сценарии их обработки, соответственно, тоже. Во-вторых, не все понимают структуру
stackTrace
, а антипаттернов обработки ошибок очень много, и каждый из них «неправилен» по-своему. Так что вариантов сделать неправильно здесь намного больше, чем где бы то ни было.Распространенные антипаттерны приведены здесь:
Неполное понимание работы операторов (арифметических, логических и других).
Простой пример. Сможешь сходу сказать, что выведет этот код?
public class Main { public static void main(String[] args) { int i = 6; System.out.println(7 == i++); } }
Если ты ответил неправильно или наугад, значит, в этой области пока есть пробелы:)
Код выведет
false
, потому что приоритет у оператора сравнения==
выше, чем у постфиксного инкремента++
. Поэтому сначала будет выполнено сравнение7 == i
, и только потом - операцияi++
.По этой теме, кстати, у нас тоже была подробная лекция. Вот ссылка, если пропустил.
Пропуск слова
break
в оператореswitch
.Эту ошибку, вероятно, допускали многие из читателей!)
public class Main { public static void main(String[] args) { int i = 1; switch (i) { case 1: { System.out.println("Число равно 1"); } case 2: { System.out.println("Число равно 2"); } case 3: { System.out.println("Число равно 3"); } } } }
В результате на них обрушивается водопад из всех возможных вариантов:
Вывод:
Число равно 1 Число равно 2 Число равно 3
Оператор
break
прерывает работу оператораswitch
в момент, когда отработал один из вариантов. Не стоит о нем забывать, иначе результат может быть неожиданным :)
John Selawsky
Senior Java-разработчик и преподаватель в LearningTree
8 частых ошибок начинающих программистов
Привет! Сегодня мы рассмотрим список из 8 распространенных ошибок начинающих (да и не только) Java-разработчиков. В Сети ты найдешь немало таких подборок: многие из них похожи друг на друга.
Когда мы составляли этот список, ориентировались на один критерий: допускали ли эти ошибки сами во время учебы и работы :) Они расставлены не по приоритету и одинаково важны для понимания и запоминания.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ